#iphone #objective-c #ios
#iPhone #objective-c #iOS
Вопрос:
Вот что я вижу, когда запускаю следующий код:
// Dealloc on MyClass not called
MyClass* c = [MyClass new];
self.a = [NSMutableArray new];
[self.a addObject:c];
[c release];
[a release];
// Dealloc on MyClass called
MyClass* c2 = [MyClass new];
NSMutableArray* a2 = [NSMutableArray new];
[a2 addObject:c2];
[c2 release];
[a2 release];
// Dealloc on MyClass called
MyClass* c3 = [MyClass new];
a = [NSMutableArray new];
[a addObject:c3];
[c3 release];
[a release];
Почему в первом примере не вызывается dealloc?
Редактировать:
Я думаю, что я все это неправильно понял. В основном, что мне нужно сделать, это:
NSMutableArray* alocal = [NSMutableArray new]; // alocal has a retain count of 1
self.a = alocal; // a has a retain count of 1
[alocal release]; // alocal has a retain count of 0
[a release]; // a has a retain count of 0
или
self.a = [[NSMutableArray new] autorelease]; // a has a retain count of 2
[a release]; // a has a retain count of 0
или
self.a = [NSMutableArray array]; // a has a retain count of 2
[a release]; // a has a retain count of 0
Просто в качестве примечания, с параметрами автоматического выпуска / массива (# 2 и # 3) a не освобождается сразу, поэтому, если вы хотите больше контроля, выберите вариант # 1.
Спасибо!
Комментарии:
1. Интересно… Итак, по сути, вы хотите, чтобы оно было освобождено прямо в этот момент, да? Ну, звучит справедливо. Обычно мы просто позволяем пулу автоматически освобождаться самостоятельно, но вы правы, он не будет выпущен сразу.
Ответ №1:
Поскольку в первом примере предполагается a
, что это свойство сохранения / копирования, массив протекает.
self.a = [NSMutableArray new];
что, кстати, отличается от третьего примера:
a = [NSMutableArray new];
В третьем случае объект присваивается непосредственно ivar (без участия установщика свойств).
Возвращаясь к первому примеру, метод new
возвращает сохраненный объект ( 1), а затем установщик свойств также сохраняет объект ( 2). Затем, когда свойство освобождается (-1), вы получаете 1. Это неправильно. Вам необходимо сбалансировать сохранение / выпуски, чтобы в итоге получить 0.
Простым решением является использование удобного конструктора:
self.a = [NSMutableArray array];
В этом случае метод array
возвращает автоматически освобожденный объект ( 0), а установщик свойств сохраняет объект ( 1), который уравновешивается освобождением свойства (-1), и в итоге получается 0.
Кроме того, в первом примере вы освобождаете объект, который вы присвоили свойству, через ivar:
[a release];
В результате свойство теперь содержит указатель на потенциально освобожденный объект. Поскольку вы отказались от права собственности на объект, нет никакой гарантии, что объект будет активен в будущем. Если объект был фактически освобожден (поскольку у него нет других владельцев), ваш указатель все равно будет указывать на адрес памяти в куче, где раньше находился объект; за исключением того, что теперь этот адрес может содержать что угодно: старый битовый шаблон указанного объекта или несвязанный объектили абсолютный мусор.
Ничего хорошего не произойдет, если вы отправите сообщение освобожденному объекту, например, это приведет к сбою вашего приложения. Чтобы избежать этого, освободите объект через свойство:
self.a = nil;
Комментарии:
1. Когда я делаю …self.a = [Массив NSMutableArray]; освобождение по-прежнему не вызывается. Также, когда я вызываю …self.a = [[NSMutableArray new] авторелиз]; освобождение по-прежнему не вызывается.
2. @user472292 Теперь, когда массив больше не протекает, он должен быть вызван. Должно быть, происходит что-то еще. Можете ли вы предоставить более подробную информацию?
3. Я уверен, что массив не протекал. Прежде чем я вызвал [релиз] Я проверил количество сохранений, и оно равнялось 1.
4. @user472292 как объявляется свойство
a
? Свойства задаютсяassign
по умолчанию, поэтому, если вы ничего не указываете, они естьassign
, что обычно используется для примитивных типов и объектов, которыми вы не владеете, как делегаты. В этом случае это должно бытьretain
илиcopy
, что является первым предположением моего поста. Итак, как оноa
объявлено?5. @свойство (неатомное, сохранить) NSMutableArray* a;
Ответ №2:
Это зависит от того, как вы реализовали свойство ‘a’, которым оно должно быть:
@property (retain) NSMutableArray *a;
также при использовании ‘new’ он помещает выделение, поэтому вы должны автоматически освободить его следующим образом:
self.a = [[NSMutableArray new] autorelease];
Комментарии:
1. Когда я делаю …self.a = [Массив NSMutableArray]; освобождение по-прежнему не вызывается. Также, когда я вызываю …self.a = [[NSMutableArray new] авторелиз]; освобождение по-прежнему не вызывается.