Вопрос освобождения объектов - PullRequest
1 голос
/ 04 июля 2011

У меня есть код:

@interface PhotoListViewController : UIViewController 
{
    IBOutlet UIImageView* firstPicContainer;
    IBOutlet UIImageView* secondPicContainer;
    UIImage* pic_one;
    UIImage* pic_two;
    IBOutlet UILabel* firstPicLabel;
    IBOutlet UILabel* secondPicLabel;
    NSString* firstPicName;
    NSString* secondPicName;
    IBOutlet UILabel* authorLabelA;
    IBOutlet UILabel* authorLabelB;
    NSString* authorName;

}
@property (retain) UIImage* pic_one;
@property (retain) UIImage* pic_two;
@property (copy) NSString* firstPicName;
@property (copy) NSString* secondPicName;
@property (copy) NSString* authorName;


@end

Вопрос в том, должен ли я выпустить целую пачку объектов или только те, чьи свойства я объявил?Например: firstPicName является NSString и сохраняется, когда установлено, его контейнером является UILabel * firstPicLabel, который назначается так:

firstPicLabel.text = firstPicName;

в -viewDidLoad.Таким образом, метка как объект не сохраняется сама по себе, а его свойство.То же самое и с другими объектами, свойства сохраняются, другие - просто контейнер.Владельцем этих контейнеров является их мнение, которое должно отвечать за их выпуск, но я немного запутался здесь, поэтому хочу прояснить этот момент.Спасибо.

Ответы [ 2 ]

1 голос
/ 04 июля 2011

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

У вас могут быть все ивары и свойства, которые вы объявили выше, но если вы не инициализировали их и / или не обращались к их свойствам, то никогда не будет объекта, который будет освобожден в первую очередь.

Правило большого пальца:

1) Если вы создаете, копируете или сохраняете объект, вы несете ответственность за его освобождение.

2) См. Правило № 1 выше.

На практике, вот несколько примеров:

@implementation...
...
pic_one = [UIImage imageNamed:@"test.png"];
...
@end

pic_one объявлен как ивар, но назначен объекту с автоматическим выпуском. Вы не должны выпускать это.

Другой пример:

@implementation....
...
self.pic_one = [UIImage imageNamed:@"test.png"];
...
@end

Вы присвоили этот объект UIImage через его оценщик / свойство, которое объявлено как сохраняемое, поэтому вы несете ответственность за его освобождение. «За кулисами», вот что происходит, когда вы присваиваете объект через его свойство (пример для свойств, объявленных как retain, копия будет немного отличаться, но тот же принцип).

- (void)setPic_One:(UIImage*)newImage
{
   if (pic_One != newImage)
   {
        [newImage retain];
        [pic_One release];
        pic_One = newImage;
   }
}

И последний:

UIImage *testImage = [[UIImage alloc] initWithImage:@"test.png"];
self.pic_one = testImage;
[testImage release];

В этом случае вы выделяете / инициируете (создаете) объект UIImage, поэтому вы несете ответственность за его освобождение. В то же время вы также присваиваете его свойству, объявленному как сохраняемое, поэтому вы обязаны также освободить его, когда закончите с этим (обычно в вашем методе dealloc).

1 голос
/ 04 июля 2011

Краткий ответ: Для любого свойства, которое вы объявляете как retain (или copy), вы должны установить его значение равным nil в вашем методе dealloc. Свойства, которые объявлены для других объектов и полей, которые вы не сохраняете сами, вам не нужно беспокоиться.

...