Выделение и выпуск iPhone - PullRequest
0 голосов
/ 05 августа 2011

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

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


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

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


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

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

10x

Ответы [ 4 ]

5 голосов
/ 05 августа 2011

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

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

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

1 голос
/ 05 августа 2011

Iphone использует модель управления памятью на основе подсчета ссылок. См. сначала это руководство , а затем техническую документацию Apple * ... theAppDataObject - это свойство (см. Использование self. TheAppDataObject)который должен быть сохранен для работы вышеупомянутого кода .. Любой объект, который сохраняется, должен иметь бонус плюс 1 счет сохранения ... Объект освобождается только тогда, когда его счет сохранения достигает нуля.

1 голос
/ 05 августа 2011

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

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

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

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

return self;
0 голосов
/ 05 августа 2011

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

- (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;
}

теперь по вашим вопросам:

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

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

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

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

...