2009-09-25 6 views
0

С переменной экземпляра туАггау:Инициализация экземпляра переменной

@interface AppController : NSObject 
{ 
    NSArray *myArray; 
} 

Иногда я вижу туАггау инициализируется так:

- (void)init 
{ 
    [super init]; 
    self.myArray = [[NSArray alloc] init]; 
    return self; 
} 

и иногда я вижу его более сложным способом:

- (void)init 
{ 
    [super init]; 
    NSArray *myTempArray = [[NSArray alloc] init]; 
    self.myArray = myTempArray 
    [myTempArray release]; 
    return self; 
} 

Я знаю, что нет никакого различия в конечном результате, но почему люди беспокоятся о том, чтобы сделать более длинную версию ?

Мое ощущение, что более длинная версия лучше, если переменная экземпляра настроена с помощью @property и @synthesize (возможно, потому, что переменная уже выделена). Это часть причины?

Спасибо.

+2

То, что вы назвали методами 'init', полностью вводит в заблуждение, поскольку ни один из них не имеет дистанционной квалификации, чтобы быть ini tializer. – bbum

ответ

2

Если myArray является собственностью и он установлен в retain или copy (как это должно быть для свойства, как это), то вы будете в конечном итоге двойной сохраняя переменную, когда вы делаете это:

self.myArray = [[NSArray alloc] init]; 

Вызов alloc устанавливает счетчик ссылок в 1, а присвоение свойства сохраняет или копирует его. (Для неизменяемого объекта copy чаще всего является просто вызовом retain, нет необходимости копировать объект, который не может изменить его значение). Таким образом, после назначения объект имеет счет 2, хотя вы только держа одну ссылку на нее. Это приведет к утечке памяти.

я бы ожидал увидеть либо прямое назначение к экземпляру переменной

myArray = [[NSArray alloc] init]; 

Или надлежащее обращение с удержанием графа:

NSArray *newArray = [[NSArray alloc] init]; 
self.myArray = newArray; 
[newArray release]; 

или использование autoreleased объектов:

self.myArray = [[[NSArray alloc] init] autorelease]; // Will be released once later 
self.myArray = [NSArray array]; // Convenience constructors return autoreleased objects 
+0

Спасибо за ответ, он очистил некоторые вещи для меня. –

0

У меня есть ощущение, что вы имели в виду это:

NSArray* a = [NSArray arrayWithObjects:@"foo", @"bar", nil]; 

и этот

NSArray* a = [[NSArray alloc] initWithObjects:@"foo", @"bar", nil]; 
//... 
[a release]; 

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

-1

Этот код разрушит ваше приложение. Вторая версия только копирует указатель и освобождает экземпляр. Вы должны позвонить [object retain], прежде чем выпустить ссылку.

1

Это идиома, используемая в мутаторах (иногда называемых «сеттерами»), но я думаю, что вы набрали ее немного неправильно. Обычно это выглядит так:

-(void)setMyName:(NSString *)newName 
{ 
    [newName retain]; 
    [myName release]; 
    myName = newName; 
} 

Новое имя сохраняется, так как этот экземпляр должен будет содержать его; старое имя выпущено; и, наконец, переменной экземпляра присваивается указание на новое имя.

Смежные вопросы