UIImageView получил странный счет сохранения, и мне нужно выпустить его дважды, чтобы избежать утечек - PullRequest
0 голосов
/ 13 мая 2011

Я получил UIImageView, который я установил в nib-файле.Я загружаю изображение из Интернета и устанавливаю изображение для UIImageView.Когда я выпускаю, он сохранил счет 2?Если я использую только 1 релиз, то не будет никакой утечки памяти, но я вижу в «Распределении инструментов», что он никогда не будет выпущен.Когда я выпускаю UIImageView дважды, как показано ниже, он работает хорошо.Но я никогда не должен выпускать его дважды?!?!

в заголовке:

IBOutlet UIImageView *background;

в .m загрузке изображения:

 /* Load Image code */
 id path = [NSString stringWithFormat:@"http://www.image.com/aImage.jpg"];
 NSURL *url = [NSURL URLWithString:path];
 NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
 NSData* urlData = [[NSData alloc] initWithContentsOfURL:url];
 [background setImage:[UIImage imageWithData:urlData]];
 [urlData release];
 [pool release];

в функции dealloc:

- (void)dealloc {
    NSLog(@"Backgroud count: %i",[background retainCount]); // Prints 2
    [background release];
    [background release]; // Does not "leak" if i have 2x release
    [super dealloc];
}

Это единственный код, использующий фон UIImageView.

РЕДАКТИРОВАТЬ:

я забыл упомянуть, что я запускаю этот код внутри цикла forкак это.но этот цикл for будет выполняться только один раз!Но это не должно иметь значения?

for (id theKey in dictionary) {
     /* Load Image code above is here */
}

Ответы [ 2 ]

3 голосов
/ 13 мая 2011

Мне кажется, я понял, в чем проблема. Apple рекомендует сохранять объекты, к которым вы подключаетесь, через IBOutlet s (в данном случае ваше изображение). Вы сказали, что не сделали этого, но должен следовать рекомендации Apple. Причина, по которой вам следует это изложить, описана в сообщении на форуме iphonedevsdk.com об этой проблеме, которое ссылается на сообщение в блоге Big Nerd Ranch , в котором все это изложено.

В iOS механизм загрузки пера использует сеттер, если он есть в вашей розетке, но в противном случае он использует кодирование значения ключа; в частности, он использует setValue:forKey:, который сохраняет значение (это задокументировано, но несколько неожиданно). Ваше представление изображения, являющееся подпредставлением вида сверху вашего контроллера представления, сохраняется этим представлением. Это также сохраняется этой процедурой установки значения ключа. Таким образом, без вашего ведома, ваши объекты имеют две ссылки на представление изображения. Apple делает предложение о сохранении собственности, чтобы вам стало известно, что представление сохраняется.

Вам по-прежнему не следует беспокоиться о количестве сохраняемых данных как таковом, но вы должны сделать одно из двух: сделать это IBOutlet сохраненным свойством и освободить его в и viewDidUnload и dealloc (хотя бы по одному разу!) Или следуйте предложению BNR и сделайте свойство явно назначенным:

@property (assign, nonatomic) IBOutlet UIImageView *background;

В этом случае вам не нужно выпускать его самостоятельно. В обоих случаях убедитесь, что у вас @synthesize права доступа к свойству.


Ранее:

Не смотрите на счет удержания , и если утечки не обнаружено, не беспокойтесь об этом. Платформа UIKit, вероятно, сохраняет представление по причинам, к которым вы не причастны.

Кроме того, если background не является сохраняемым свойством:

@property (retain) IBOutlet UIImageView *background;

и вы создаете его в xib, вы не должны выпускать его вообще , потому что вы не являетесь его владельцем. То есть вы не несете ответственности за его память ; Действия, которые возлагают на вас эту ответственность: вызов retain объекта или его создание с использованием метода, имя которого начинается с alloc, copy, mutableCopy или new.

.
0 голосов
/ 13 мая 2011

Я не знаю много о файле пера, я привык следовать, как показано ниже

  background=[[UIImageView alloc] initWithFrame:CGRectMake(0,0,320,480)];
  //Now the reatin count is 1
 [background setImage:[UIImage imageWithData:urlData]];
  [someView addSubview:background];
  //Now the ratainCount will be 2 since we added the imageview to the superview
  [background release];
 //i will release immediately so the retain count drops to 1
 . . . 


//in dealloc or viewDidDisaaper i will remove the imageview from its superview
//then the retainCount will become 0 and the instance will be deallocated.
//it works for we without any memory leakage
[background removeFromSuperview];
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...