Почему мой addSubview: метод вызывает утечку? - PullRequest
0 голосов
/ 06 февраля 2011

Ладно, я провел массу исследований по этому вопросу и потратил несколько дней, пытаясь выяснить, почему утечка следующего кода:

[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
UIImage *comicImage = [self getCachedImage:[NSString stringWithFormat:@"%@%@%@",@"http://url/",comicNumber,@".png"]];
self.imageView = [[[UIImageView alloc] initWithImage:comicImage] autorelease];
[self.scrollView addSubview:self.imageView];
self.scrollView.contentSize = self.imageView.frame.size;
self.imageWidth = [NSString stringWithFormat:@"%f",imageView.frame.size.width];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

И self.imageView, и self.scrollView - это @propety (nonatomic, retain) и выпущен в моем dealloc .. imageView больше нигде в коде не используется.Этот код также запускается в потоке вне основного потока.Если я запускаю этот код на своем устройстве, он быстро исчерпает память, если я постоянно загружаю это представление.Тем не менее, я обнаружил, если закомментировал следующую строку:

[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;
UIImage *comicImage = [self getCachedImage:[NSString stringWithFormat:@"%@%@%@",@"http://url/",comicNumber,@".png"]];
self.imageView = [[[UIImageView alloc] initWithImage:comicImage] autorelease];
//[self.scrollView addSubview:self.imageView];
self.scrollView.contentSize = self.imageView.frame.size;
self.imageWidth = [NSString stringWithFormat:@"%f",imageView.frame.size.width];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

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

Ответы [ 3 ]

1 голос
/ 06 февраля 2011

Вы автоматически выпускаете свой просмотр изображений при инициализации, а затем сохраняете его, назначая его для self.imageView, а затем добавляя его как подпредставление, сохраняя его снова. Таким образом, когда пул истощается, он получает сообщение об освобождении. Когда это удалено как подпредставление, это получает сообщение выпуска. Затем, если вы удаляете, он получает третье сообщение о выпуске. Один из этих трех не встречается. Вы говорите, что он выпущен в dealloc, так что это не так. В какой-то момент пулу автозапуска можно доверять, так что это не так. В какой-то момент я либо удалил его как подпредставление, либо избавился бы от одного из ваших сохраненных вызовов.

И .. не должно ли это:

self.imageView = [[[UIImageView initWithImage:comicImage] autorelease];

быть этим?:

self.imageView = [[UIImageView alloc] initWithImage:comicImage];
0 голосов
/ 06 февраля 2011
[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

Прекрасно.

UIImage *comicImage = [self getCachedImage:[NSString stringWithFormat:@"%@%@%@",@"http://url/",comicNumber,@".png"]];

Не вызывайте методы get* ничего, если вы не следуете стандартным образцам Какао (которым этот метод не является).Просто назовите это cachedImage:.

self.imageView = [[[UIImageView initWithImage:comicImage] autorelease];

Вы пропускаете alloc звонок;это должно быть:

self.imageView = [[[UIImageView alloc] initWithImage:comicImage] autorelease];

Или (если вы хотите избежать пула автоматического выпуска; возможно, здесь нет проблем):

UIImageView *iV = [[UIImageView alloc] initWithImage:comicImage];
self.imageView = iV;
[iV release];
[self.scrollView addSubview:self.imageView];
self.scrollView.contentSize = self.imageView.frame.size;
self.imageWidth = [NSString stringWithFormat:@"%f",imageView.frame.size.width];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;

Все хорошо.Если есть утечка, это или потому, что imageView не выпущен в dealloc или что-то еще висит на нем (scrollView не освобождается, возможно?).Приборы могут замечательно отслеживать утечки и т. Д.

Инструмент «утечки» ищет объекты, которые больше не имеют ссылок на них.В этом случае вполне вероятно, что у вас остались оставшиеся ссылки.

Честно говоря, учитывая, что вы легко можете воспроизвести рост путем повторения, анализ Heapshot будет весьма вероятен.

Я написал руководство по анализу Heapshot немного назад.

0 голосов
/ 06 февраля 2011

При вызове этой строки:

[self.scrollView addSubview:self.imageView];

self.imageView сохраняется в его супер-представлении, и когда вам больше не нужен imageView, вы должны вызвать:

[self.imageView removeFromSuperview];

Это будетвызов вызова на self.imageView.

ps Вы можете отслеживать количество ссылок, позвонив

NSLog(@"RefCount: %d", [self.imageView retainCount]);

, добавив эту строку выше

self.imageView = [[[UIImageView initWithImage:comicImage] autorelease];

для отслеживания refCount.(Лучше использовать инструменты, но вы уже знаете, что:))

Редактировать: Хорошая практика - [[alloc] init] объекты, когда у вас есть свойства, подобные этому:

UIView *myView = [[UIView alloc] init];
self.myCustomView = myView;
[myView release];

В противном случае вы получите self.myCustomView, сохраненное дважды.

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