ваша проблема в том, как вы его выпускаете:
- (void)viewDidLoad{
[super viewDidLoad];
self.tstImageView = [[UIImageView alloc] //<==This object is leaking
initWithFrame:<SomeFrame>];
self.tstImageView.image = [UIImage imageNamed:@"SomeImage.png"];
[self.view addSubview:tstImageView];
[tstImageView release]; // << here
}
вы должны сделать это так:
- (void)viewDidLoad{
[super viewDidLoad];
UIImageView * imageView = [[UIImageView alloc] initWithFrame:<SomeFrame>];
imageView.image = [UIImage imageNamed:@"SomeImage.png"];
self.tstImageView = imageView;
[imageView release];
[self.view addSubview:self.tstImageView];
}
Программа проверки верна, потому что она не может предполагать, что переменная идентична той, которую вы установили. Следовательно, форма, которую вы используете в OP, может привести к дисбалансу счетчика ссылок, потому что значение ivar может не совпадать с тем, что вы ему присвоили к моменту выпуска сообщения на ivar.
Эти случаи маловероятны для UIImageView
и весьма маловероятны в контексте вашей программы, но эти примеры должны дать вам представление о том, почему средство проверки предполагает, что ассоциациям object-> ivar нельзя доверять:
Между созданием представления изображения и сообщением о его выпуске через ivar у вас есть:
self.tstImageView = [[UIImageView alloc] initWithFrame:<SomeFrame>];
self.tstImageView.image = [UIImage imageNamed:@"SomeImage.png"];
[self.view addSubview:tstImageView];
1) назначение вида изображения через сеттер 2) доступ к просмотру изображения через геттер 3) прямой доступ к ivar при добавлении в self.view
- сеттер мог взять скопированное или использовать кэшированное значение.
UIImageView
- плохой пример, но программа проверки не знает, как обычно передаются типы - даже если бы это было так, она (временами) сделала бы небезопасные предположения.
Самый простой пример:
- (void)setName:(NSString *)inName {
NSString * prev = name;
if (inName == prev) return;
if (0 == [inName count]) name = @"";
else name = [inName copy];
[prev release];
}
- Стоимость ивара за это время может измениться. вряд ли проблема в этом случае, но предположим, что добавление представления изображения в качестве подпредставления может привести к обратному вызову и изменению
self
в процессе / эффекте добавления подпредставления и замене или удалению переданного представления изображения. В этом случае представление переменной, которое вы передали, утекло бы, а представление, которым оно его заменило, имело бы отрицательный дисбаланс.
Ни то, ни другое не вероятно произойдет в вашем примере, но это действительно происходит в реальных программах, и средство проверки правильно оценивает на основе местоположения, а не свойства (средство проверки не может предполагать большую часть того, что происходит внутри вызова метода). В этом случае он также поощряет один хороший идиоматический стиль.
РЕДАКТИРОВАТЬ: Есть ли утечка?
Хорошо, я запустил вышеуказанный проект, используя инструмент Leak в приборе. Он не показал никаких утечек, хотя я пробовал это много раз. Кому я должен верить? Статический анализатор или прибор для проверки утечек?
Статический анализатор сообщает, что существует потенциальная утечка, поскольку он не может гарантировать, что ссылка / выделение, за которым он следует, правильно сохранены / освобождены. Вы можете гарантировать правильный подсчет ссылок и порадовать статический анализатор, изменив свою программу так, чтобы она выглядела так, как я написал ее в моем примере.
То, как вы это написали, лишило анализатор возможности следовать ссылке.
Если у вас нет утечек и нет зомби, значит, утечки нет. Но решение легко исправить - и программы могут меняться в процессе разработки. Гораздо проще использовать опубликованную мною форму, чтобы облегчить набору инструментов и вам проверить правильность программы. Статический анализатор не всегда работает правильно, но вы должны настроить свои программы так, чтобы ему было удобно, потому что статический анализ очень полезен. Программу, которую я разместил, также легче понять и подтвердить, что она верна.
person
justin
schedule
03.11.2011