Согласно исходному коду Clang для генерации кода блоков Objective-C.
Objective-C блоки буквенные порождается EmitBlockLiteral
функции.
llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
LLVM document объясняет глубоко, что блок буквальным. В любом случае эта функция генерирует дескриптор блока и вспомогательную функцию копирования указанного блока. Вспомогательная функция копирования предназначена для записи автоматических переменных и self
.
buildBlockDescriptor -> buildCopyHelper -> GenerateCopyHelperFunction
В GenerateCopyHelperFunction
функции, Clang излучает objc_storeStrong
для каждого Objective-C объект автоматической переменной, которая будет захвачен блоком.
for (const auto &CI : blockDecl->captures()) {
...
EmitARCStoreStrongCall(...
Таким образом, эта линия будет подсчитывать сохранить кол self
(1 -> 2).
После этого функция EmitBlockLiteral
испускает objc_retain
для каждой переменной объекта объекта Objective-C, которая также будет захвачена блоком.
// Next, captured variables.
for (const auto &CI : blockDecl->captures()) {
...
EmitExprAsInit -> EmitScalarInit -> EmitARCRetain
Поэтому эта строка будет подсчитывать сохранить кол self
тоже (2 -> 3).
Я не знаю точно, почему. Но, по-видимому, есть некоторая причина, чтобы сохранить объект Objective-C перед захватом объекта с помощью вспомогательной функции копирования блока.
Блок захочет сохранить «захваченные» iVars (например, self), чтобы гарантировать, что ссылка остается в силе ... то есть, что 'self' не освобождается, прежде чем она будет выполнена.Вы найдете хорошую информацию об этом здесь (другое обращение к MRC и ARC. Http://stackoverflow.com/questions/19227982/using-block-and-weak – YvesLeBorg
Также для лучшего понимания слабого чтения https: //dhoerl.wordpress. com/2013/04/23/i-finally-figured-out-weakself-and-strongself/ –
http://whentouseretaincount.com – jrturton