objective-c - objective - autoreleasepool swift




Почему @autoreleasepool все еще нуждается в ARC? (4)

ARC не избавляется от сохранений, выпусков и автореализаций, он просто добавляет в нужные вам. Таким образом, есть все еще призывы к сохранению, есть еще призывы к выпуску, есть еще призывы к автообновлению, и все еще есть пулы автовыпусков.

Одним из других изменений, которые они внесли с новым компилятором Clang 3.0 и ARC, является то, что они заменили NSAutoReleasePool на директиву компилятора @autoreleasepool . NSAutoReleasePool всегда был немного особенным «объектом», и они сделали это так, чтобы синтаксис использования одного не смешивался с объектом, так что он, как правило, несколько проще.

Так что в принципе, вам нужно @autoreleasepool потому что по-прежнему есть автоблокировки, о которых можно беспокоиться. Вам просто не нужно беспокоиться о добавлении в autorelease звонки.

Пример использования пула автоматического выпуска:

- (void)useALoadOfNumbers {
    for (int j = 0; j < 10000; ++j) {
        @autoreleasepool {
            for (int i = 0; i < 10000; ++i) {
                NSNumber *number = [NSNumber numberWithInt:(i+j)];
                NSLog(@"number = %p", number);
            }
        }
    }
}

Ужасно надуманный пример, конечно, но если у вас не было @autoreleasepool внутри внешнего for -loop, тогда вы будете выпускать 100000000 объектов позже, а не 10000 каждый раз вокруг внешнего for -loop.

Обновление. Также см. Этот ответ - https://stackoverflow.com/a/7950636/1068248 - для чего @autoreleasepool имеет никакого отношения к ARC.

Обновление: я взглянул на внутренности того, что здесь происходит, и написал его в своем блоге . Если вы посмотрите там, вы увидите, что именно делает ARC и как новый стиль @autoreleasepool и как он вводит область применения, используется компилятором для вывода информации о том, что нужно сохранить, выпускать и автореализовать.

По большей части с ARC (Automatic Reference Counting) нам вообще не нужно думать об управлении памятью объектами Objective-C. NSAutoreleasePool не разрешено создавать NSAutoreleasePool , но есть новый синтаксис:

@autoreleasepool {
    …
}

Мой вопрос: зачем мне это когда-нибудь понадобиться, когда я не должен вручную выпускать / автореализовать?

EDIT: Подводя итог тому, что я получил из всех участников и комментариев лаконично:

Новый синтаксис:

@autoreleasepool { … } - новый синтаксис для

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
…
[pool drain];

Важнее:

  • ARC использует autorelease а также release .
  • Для этого нужен пул автоматического выпуска.
  • ARC не создает пул автовыпусков для вас. Однако:
    • В главном потоке каждого приложения Cocoa уже есть пул авторесурсов.
  • Есть два случая, когда вы можете использовать @autoreleasepool :
    1. Когда вы находитесь во вторичном потоке и нет пула myRunLoop(…) { @autoreleasepool { … } return success; } , вы должны сделать свой собственный, чтобы предотвратить утечки, такие как myRunLoop(…) { @autoreleasepool { … } return success; } myRunLoop(…) { @autoreleasepool { … } return success; } .
    2. Когда вы хотите создать более локальный пул, как показал @mattjgalloway в своем ответе.

Кажется, что существует большая путаница в этой теме (и по крайней мере 80 человек, которые, вероятно, сейчас смущены этим и считают, что им нужно посыпать @autoreleasepool вокруг своего кода).

Если проект (включая его зависимости) использует исключительно ARC, то @autoreleasepool никогда не должен использоваться и ничего не будет полезен. ARC будет обрабатывать выпуски объектов в нужное время. Например:

@interface Testing: NSObject
+ (void) test;
@end

@implementation Testing
- (void) dealloc { NSLog(@"dealloc"); }

+ (void) test
{
    while(true) NSLog(@"p = %p", [Testing new]);
}
@end

дисплеи:

p = 0x17696f80
dealloc
p = 0x17570a90
dealloc

Каждый объект тестирования освобождается, как только значение выходит за пределы области видимости, не дожидаясь выхода из автозапуска. (То же самое происходит с примером NSNumber, это просто позволяет нам наблюдать за dealloc.) ARC не использует autorelease.

Причина @autoreleasepool по-прежнему разрешена для смешанных проектов ARC и не ARC, которые еще не полностью перешли на ARC.

Если вы вызываете код без ARC, он может вернуть объект с автореализацией. В этом случае вышеуказанный цикл будет протекать, поскольку текущий пул авторесурсов никогда не будет удален. Вот где вы хотите поставить @autoreleasepool вокруг блока кода.

Но если вы полностью сделали переход ARC, тогда забудьте об autoreleasepool.


Цитируется из https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html :

Блоки и потоки пулов Autorelease

Каждая нить в приложении Cocoa поддерживает собственный стек блоков пула авторекламы. Если вы пишете программу, основанную только на Foundation, или если вы отсоединяете поток, вам нужно создать свой собственный блок пула автозапуска.

Если ваше приложение или поток долговечны и потенциально генерируют много автореализованных объектов, вы должны использовать блоки пула автозапуска (например, AppKit и UIKit делать на основном потоке); в противном случае автореализованные объекты накапливаются, а объем памяти увеличивается. Если ваш выделенный поток не выполняет вызовы Cocoa, вам не нужно использовать блок пула автозаполнения.

Примечание. Если вы создаете дополнительные потоки с использованием API-интерфейсов потоков POSIX вместо NSThread, вы не можете использовать Cocoa, если Cocoa не находится в режиме многопоточности. Какао переходит в режим многопоточности только после отсоединения его первого объекта NSThread. Чтобы использовать Cocoa для вторичных потоков POSIX, ваше приложение должно сначала отсоединить хотя бы один объект NSThread, который может немедленно выйти. Вы можете проверить, работает ли Cocoa в многопоточном режиме, когда метод класса NSThread isMultiThreaded.

...

В автоматическом подсчете ссылок или в ARC система использует одну и ту же систему подсчета ссылок, что и MRR, но она вставляет соответствующие вызовы метода управления памятью во время компиляции. Вам настоятельно рекомендуется использовать ARC для новых проектов. Если вы используете ARC, как правило, нет необходимости понимать базовую реализацию, описанную в этом документе, хотя в некоторых ситуациях это может быть полезно. Дополнительные сведения о ARC см. В разделе Переход к примечаниям о выпуске ARC.


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





automatic-ref-counting