Objective-C - Утечка выделения строки в стиле C? - PullRequest
1 голос
/ 24 сентября 2011

У меня очень простое приложение. С главного экрана я запускаю новый вид («вид обучения»), который отображает изображение и метку. в режиме обучения есть кнопка меню и следующая кнопка. Когда пользователь нажимает следующую кнопку, представление обновляет изображение и метку из массива char * строк C. Однако, когда я делаю это, распределение инструментов показывает постоянно увеличивающееся количество распределений, которые не уменьшаются, когда представление уничтожается нажатием кнопки меню. Если я просто отображаю представление обучения, затем нажимаю на меню, проблем нет, выделения увеличиваются, а затем возвращаются к предыдущему уровню, но если я щелкаю следующее обновление label.text, то производятся распределения, которые не восстанавливаются. Приборы не сообщают об утечках. Вот соответствующие фрагменты кода:

LearnVC.h

@interface LearnVC : UIViewController {

    IBOutlet UIImageView *imageView;
    IBOutlet UILabel *labelView1;
    NSInteger page;

}
@property (retain, nonatomic) UIImageView *imageView;
@property (retain, nonatomic) UILabel *labelView1;

@property NSInteger page;

- (IBAction)handleNext;
- (IBAction) gotoMenu;

@end

LearnVC.m

#import ...

char *states[] { "Alabama", "Alaska", "Arizona", ... };
#define maxStates 50

@implementation LearnVC

@synthesize ...

- (void)viewDidLoad
{

      NSString *tstring;
      self.page = 0;


      //test!!!!
      tstring = [[NSString alloc] initWithCString:states[self.page] encoding:NSUTF8StringEncoding];
      labelView1.text = tstring;
      [tstring release];

      [super viewDidLoad];

}

- (IBAction) handleNext {

      NSString *tstring;
      self.page++;
      if (self.page > maxStates-1) {
           self.page = 0;
      }

      //test!!!!
      tstring = [[NSString alloc] initWithCString:states[self.page] encoding:NSUTF8StringEncoding];
      labelView1.text = tstring;
      [tstring release];

}

- (void)dealloc
{

      [imageView release];
      [labelView1 release];
      [super dealloc];

}

Похоже, это происходит каждый раз, когда я обновляю представление, не удаляя (не освобождая) его и не добавляя заново. Есть ли что-то со старыми массивами Си, которые не копируются / не выпускаются должным образом. Или какая-то проблема со свойствами UILabel.text, которые не освобождают память? Любая помощь приветствуется.

Заранее спасибо, Нил

Я преобразовал его для использования NSArray -

Я добавил это в .h файл

NSArray *statesArray;

и @property (retain, nonatomic) NSArray * statesArray;

затем в .m файле

в viewDidLoad

NSArray *objects = [NSArray arrayWithObjects:@"Alabama", @"Montgomery",
                    @"Alaska", @"Juneau" ,..., nil];

self.statesArray = objects;

//I assume that since I didn't init it, I don't need to release objects.

labelView1.text = [self.statesArray objectAtIndex:self.page];in dealloc

[statesArray release];

Тогда в моей ручкеСледующий

labelView1.text = [self.statesArray objectAtIndex:self.page];

Я пробегаю весь массив, выхожу, перезагружаюсь и т. Д. и ассигнования увеличиваются в первый раз, но прекращают расти после того, как я однажды прошел список. Это было не так с массивом char *, должно быть, что-то еще происходит, ну да ладно, мне просто нужно избавиться от своих старых способов C и придерживаться классов NS / UI.

Кажется, это решило проблему. Теперь я поработаю над загрузкой изображения и посмотрю, работает ли оно так же.

Ответы [ 2 ]

2 голосов
/ 24 сентября 2011

Метод initWithCString:encoding: может сделать внутреннюю копию строки C, которую вы передаете, но не гарантируется освобождение копии во время освобождения.Поскольку передаваемые вами строки C являются постоянными и поэтому никогда не могут быть освобождены, вы можете вместо этого использовать initWithBytesNoCopy:length:encoding:freeWhenDone:, чтобы избежать создания дополнительных копий.Например:

NSString *s = [[NSString alloc] initWithBytesNoCopy:someCString
                                             length:strlen(someCString)
                                           encoding:NSUTF8StringEncoding
                                       freeWhenDone:NO];
0 голосов
/ 25 сентября 2011

Кроме того, система выполняет большое кеширование, так как каждый элемент управления может кэшировать использованный текст. Я обнаружил, что если я прогоню серию пару раз, то распределение перестанет расти, как если бы он кешировал все, что собирался. Распределения не снижались до начальной точки при выходе из режима обучения, но последующие запуски больше не добавлялись.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...