-dealloc метод не вызывается при владении массивом dealloc'd ... не так ли? - PullRequest
1 голос
/ 25 января 2011

Вот две части кода Objective-C в приложении Foundation.Этот фрагмент кода находится в функции:

    [arrayOfObjects addObject:[[TheShape alloc] init]];
    NSLog(@"%@", arrayOfObjects); // log verifies "<TheShape..." is in the array
    [arrayOfObjects release];

и в моем классе TheShape у меня есть метод переопределения dealloc:

    - (void)dealloc {
        NSLog(@"TheShape dealloc called.");
        [super dealloc];
    }

Хотя моя программа работает иначе, она нене так, как я ожидаю.Когда будет отправлено сообщение [arrayOfObjects release], я ожидаю увидеть строку «TheShape dealloc ...» в журнале.Это не так.

Q1: Почему бы и нет?

Так что я немного копаю и упрощаю вещи.Если я сделаю что-нибудь попроще, как это:

    TheShape *aShape = [[TheShape alloc] init];
    [aShape release];

, сообщение отладки все равно не появится в журнале.

Q2: почему бы и нет?

Но если я это сделаюэто:

    TheShape *aShape = [TheShape new];
    [aShape release];

сообщение отладки действительно появляется в журнале.Сообщение отладки также появляется в журнале, если я изменил alloc / init в первом примере тоже на new.

Q3: Почему?

Очевидно, я упускаю что-то концептуальноев цикле alloc / init / release (вопросы 1 и 2) и в предполагаемой эквивалентности new и alloc/init (Q3).Кто-нибудь может указать мне на учебник, который объясняет вещи немного больше для мышления, как я?

Спасибо,

Билл

Ответы [ 3 ]

5 голосов
/ 25 января 2011

Случайно ли вы переопределили +new в своем классе? Он должен делать то же самое, что и +alloc/-init.

В любом случае, ваша самая первая строка

[arrayOfObjects addObject:[[TheShape alloc] init]];

пропускает ваш TheShape экземпляр. Вы должны превратить это в

[arrayOfObjects addObject:[[[TheShape alloc] init] autorelease]];
1 голос
/ 25 января 2011

Эта ссылка предоставляет полезную информацию об управлении памятью.

1 голос
/ 25 января 2011

Нет причины для вызова метода dealloc: у вашего объекта все еще ненулевой счетчик ссылок.

Каждый раз, когда вы создаете объект, он начинает свое существование со счетчика ссылок 1.Как только этот счет достигает 0, он освобождается.Существуют определенные правила для управления памятью, которые помогают нам всем оставаться в здравом уме.Эти правила говорят о «владении объектом».

По сути, вы становитесь владельцем объекта, если выполняете одно из следующих условий:

  • Вы вызываете retain для объекта;
  • Вы получаете объект, вызывая copy или mutableCopy для другого;
  • Вы вызываете метод alloc для объекта.

Всякий раз, когда вы владеете объектом, вы несете ответственность за освобождение, если он вам больше не нужен .Он будет удален только в том случае, если он больше никому не нужен.

В вашем фрагменте вы создаете объект, который вы передаете в свой массив.Ваш массив начинает использовать его, поэтому он вызывает retain (так что он остается в живых, пока его удерживают).Однако, как только вы release массиве, ваш объект все еще должен быть освобожден вами , так как вы вызвали метод alloc.


EDIT Простой фрагмент:

TheShape *aShape = [[TheShape alloc] init];
[aShape release];

должен показать сообщение, хотя.: /

Есть две причины, по которым я вижу, что этого не происходит:

  • Вы сделали что-то странное с помощью метода alloc, init или release (в которомcase, опубликуйте свой код);
  • Вы работаете в сборщике мусора, и dealloc просто никогда не будет вызываться (это finalize, которое вы должны использовать в этом случае).Хотя я не понимаю, почему +new тогда release даст тогда ожидаемые результаты.
...