iPhone - Проблемы с управлением памятью - PullRequest
1 голос
/ 21 апреля 2010

Я перебираю свой код и пытаюсь понять, как правильно управлять памятью. Этот код:

imageView = [[[UIImageView alloc] initWithImage:myImage] autorelease];

Вызывает сбой моего приложения. Я использую несколько контроллеров представления в контроллере панели навигации. Приложение работает нормально: я могу выбрать человека из первого контроллера вида (просмотр таблицы), и оно помещает меня в список фотографий этого человека, затем я могу выбрать фотографию из этого контроллера просмотра (просмотр таблицы) и перейти к окончательному виду с скроллвью для просмотра фото. После того, как я нажал на панель навигации, загружается предыдущее представление (список фотографий в виде таблицы), однако приложение вылетает прямо перед отменой выбора строки с помощью этого кода:

- (void)viewDidAppear:(BOOL)animated {
    [super viewDidAppear:animated];  
    if(RowSelected != nil)
    {
        [MainTableView deselectRowAtIndexPath:RowSelected animated:YES];
    }
}

Выбранная строка сохраняется, когда пользователь щелкает строку.

Если я оставлю код как:

imageView = [[UIImageView alloc] initWithImage:myImage];

Приложение работает нормально. Я делаю что-то неправильно? Разве мне не нужно это автоматически выпускать?

Ответы [ 3 ]

3 голосов
/ 21 апреля 2010

Убедитесь, что вы создаете это представление в контроллере представления -loadView или -viewDidLoad, а не в его инициализаторе. Когда представление контроллера выходит за пределы экрана, оно обычно освобождается, что, в свою очередь, освобождает его подпредставления; таким образом, вы не должны ожидать, что ваша ссылка на imageView останется действительной. Если вам по какой-то причине необходимо, чтобы представление изображений оставалось в памяти, даже если контроллер представления находится за пределами экрана, тогда нормально не вызывать -autorelease при создании; просто убедитесь, что вы набрали [imageView release]; на вашем контроллере -dealloc.

0 голосов
/ 21 апреля 2010

ImageView в моем .h. Я использую эту строку в моем -viewDidLoad, мне не нужно представление, когда оно выходит за экран:

imageView = [[[UIImageView alloc] initWithImage:myImage] autorelease];

Я думаю, что я делаю, назначая выделенный UIImageView моему imageView, и если я автоматически освобождаю, то отсрочка будет отключена, потому что мой -dealloc освобождает? (извините, если я не прав)

если я проверю свой -dealloc:

- (void)dealloc {
NSLog(@"%i", [photo retainCount]);
[photo release];

NSLog(@"%i", [imageView retainCount]);
[imageView release];    
[super dealloc];

}

В NSLog значение сохранения для imageView равно 1, я предполагаю, что когда он собирается сделать [super dealloc], он пытается сделать еще 1 отсчет сохранения для imageView, когда он уже равен 0 из-за [выпуска imageView]

если у меня есть строка: imageView = [[UIImageView alloc] initWithImage:myImage]; затем в NSLog число сохранений равно 2, 1 поступает в [supper dealloc]

если я использую метод kk6yb , то приложение работает без проблем, однако я думаю, что мне не нужно было бы делать это таким образом, потому что, используя его, я проверяю счет сохранения в dealloc it также 2 в NSLog ...

Я в замешательстве, я вчера много читал об управлении памятью, чтобы лучше справиться с ситуацией, поскольку я выпускаю imageView в -dealloc. Мне кажется, мне не нужно автоматически выпускать эту строку?

Есть ли способ проверить утечки памяти в xCode?

Спасибо!

0 голосов
/ 21 апреля 2010

Когда вы отмечаете imageView для автоматического выпуска, он будет выпущен в следующий раз через цикл выполнения. Если вы все еще ссылаетесь или используете imageView где-то, то вы используете указатель на освободившееся пространство кучи. Пространство кучи будет перезаписано (рано или поздно), и вы будете ссылаться на мусор и сбой.

Я думаю, что правильное решение состоит в том, что imageView должен быть свойством, которое сохраняется, но я не уверен, что вы делаете с imageView, поэтому я только предполагаю здесь. Если вы добавите imageView в ваше представление Controllers view, оно сохранит его в массиве subviews. В итоге, он должен быть сохранен тем, кто его использует.

Вы бы сделали imageView сохраненным свойством в файле .h:

@property (nonatomic, retain) UIImageView* imageView;

Затем воспользуйтесь установщиком, который его сохранит:

UIImageView* tmpIV = [[UIImageView alloc] initWithImage:myImage];
self.imageView = tmpIV;   // copy the pointer, setter will retain it
[tmpIV release];          // release the original alloc

Не забудьте @synthesize, чтобы создать сеттер / геттер.

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