Кто владеет объектами автоматического выпуска? - PullRequest
2 голосов
/ 17 ноября 2011

В руководстве target-c написано что-то вроде

return [[[SomeClass alloc] init] autorelease];

может быть выполнено, и тогда release не требуется ни в какой момент, даже не в функции, которая получила этот объект. Кому тогда принадлежит этот объект? когда он будет выпущен?

1 Ответ

7 голосов
/ 17 ноября 2011

Ток NSAutoreleasePool делает и позаботится об освобождении при сливе.

IBAction вызовы помещаются в NSAutoreleasePool, который истощается после вызова.

Для всех вызовов, не относящихся к IBAction, применяется следующее:

Скажем, у вас есть следующие методы:

- (id)foo {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    SomeClass *bar = [self bar]; //bar still exists here
    //do other stuff
    //bar still exists here
    //do other stuff
    //bar still exists here
    [pool drain]; //bar gets released right here!
    //bar has been released
}

- (id)bar {
    return [[[SomeClass alloc] init] autorelease]; //bar will still be around after the return
}

Рассмотрим другой сценарий:

- (void)foo {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    //do other stuff
    [self bar];
    //do other stuff
    [pool drain]; //the string from blee would be released right here;
}

- (void)bar {
    [self baz];
}

- (void)baz {
    NSString *string = [self blee];
}

- (id)blee {
    return [NSString string]; //autoreleased
}

Как видите, автоматически освобожденный строковый объект даже не нужно было использовать или возвращать в область, в которой был создан пул.

NSAutoreleasePools существуют в стеке (по одному на поток), и автоматически выпущенные объекты становятся собственностью пула, который является самым верхним на момент вызова autorelease.


Обновление: Если вы имеете дело с узким циклом и хотите, чтобы объем памяти оставался умеренным, не замедляя цикл, подумайте над тем, чтобы сделать что-то подобное:

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for (NSUInteger i = 0; i < 1000000000; i++) {
    [NSString stringWithString:@"foo"];
    if (i % 1000 == 0) {
        [pool drain];
        pool = [[NSAutoreleasePool alloc] init];
    }
}
[pool drain];

Однако NSAutoreleasePool высоко оптимизирован, поэтому один пул на итерацию обычно не представляет большой проблемы.


Чтобы полностью понять, как работает NSAutoreleasePools, прочитайте эту отличную статью Майка Эша

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...