2011-08-05 3 views
0

Я новичок в ObjC и iPhone.iPhone alloc и release

Я загрузил пример совместного использования данных между несколькими видами. Основной подход - создать объект модели данных в базовом UIApplication и получить/установить данные из/на него. So in the init method i видел следующий код:


- (id) init; 
{ 
    self.theAppDataObject = [[ExampleAppDataObject alloc] init]; 
    [theAppDataObject release]; 
    return [super init]; 
} 

И после этого, используя делегат, мы можем получить доступ к этому объекту.


id theDelegate = (id) [UIApplication sharedApplication].delegate; 
    ExampleAppDataObject* theDataObject; 
    theDataObject = (ExampleAppDataObject*) theDelegate.theAppDataObject; 

Итак, мой вопрос в первом примере кода. Почему нам нужно выделить память для объекта theAppDataObject, а сразу после этого - освободить объект? Почему бы нам не получить нуль при доступе к этому объекту позже?

10x

+0

Каков источник этого примера? Это не соответствует официальным рекомендациям для методов init (т.е. первая строка должна иметь значение 'if (! (Self = [super init])) return nil;' – jv42

ответ

5

Я предполагаю, что theAppDataObject объявлен как @property (retain). Поэтому при настройке объекта, выполнив self.theAppDataObject (или [self setTheAppDataObject:]), это свойство сохранит ExampleAppDataObject. Поэтому вы можете освободить его впоследствии.

Когда вы выберете и запустите объект ExampleAppDataObject, счетчик удержит до 1. Когда вы устанавливаете AppDataObject в этот ExampleAppDataObject, он отправляет ему сохранение, поэтому количество удержаний увеличивается до 2. Затем вы можете освободить свой собственный владение объектом; он не будет освобожден, потому что у объекта AppDataObject все еще есть право собственности.

Если это имеет смысл.

+0

Итак, вы правы в этом. Но почему приращение alloc и init счетчик до 2? –

+1

Строка инициализации alloc увеличивает счетчик сохранения 'ExampleAppDataObject' до 1. Когда вы используете установщик' theAppDataObject', этот объект отправляет 'keep' в' ExampleAppDataObject', и счетчик удержаний увеличивается до 2. Поэтому вы можете освободить свою собственность на объект. – cabaret

1

Это зависит от того, как определено свойство theAppDataObject. Если он содержит вспомогательный аксессуар для удерживающего устройства, счетчик сохранения appDataObject будет переворачиваться до 2, что больше, чем необходимо здесь.

Итак, отпустите один из них.

лучше и более понятным способом было бы написать

if ((self = [super init])) { 
    ExampleAppDataObject *myAppDataObject = [[ExampleAppDataObject alloc] init]; 
    self.theAppDataObject = myAppDataObject; 
    [myAppDataObject release]; 
} 

return self; 
1

Iphone использует управление памятью на основе счетчика ссылок model..See this учебник первый, а затем apple's техническая документация ... theAppDataObject это свойство (см использование of theAppDataObject), который должен быть сохранен для того, чтобы приведенный выше код работал. Любой объект, который сохраняется, должен иметь бонус плюс 1 счетчик удержания ... Объект освобождается только после того, как его количество удержания становится равным нулю.

0

первые вещи: этот пример кода ужасен.

- (id) init 
{ 
    // assign self. super may return another address 
    self = [super init]; 
    // then check for nil 
    if (self != nil) { 
      // then assign the ivar directly because you should 
      // not invoke methods of partially constructed objects 
     theAppDataObject = [[ExampleAppDataObject alloc] init]; 
    } 
    // then return the address super returned 
    return self; 
} 

теперь вопросы:

Почему мы должны Alloc память для объекта theAppDataObject, и сразу же после этого - освободить объект?

self.theAppDataObject звонков через сеттер, который сохраняет копию, или назначает theAppDataObject. в этом случае мы можем предположить, что он, скорее всего, будет сохранен.

Почему мы не получаем нуль при доступе к этому объекту позже?

release не устанавливает указатель на нуль. он отправляет сообщение объекту, который затем уменьшает количество удержаний (в типичном случае). то, что вы ожидали в этом случае, является объектом, который был освобожден. это не происходит, когда аргумент сохраняется, поскольку счетчик ссылок не достигает нуля в программе, которую вы показали. объект все еще жив, потому что он сохранен, и адрес объекта, который хранится при вызове установщика (self.theAppDataObject = arg).