В чем разница между слабой и блочной ссылкой?
я читаю документацию Xcode, и вот что меня озадачивает:
__block typeof(self) tmpSelf = self;
[self methodThatTakesABlock:^ {
[tmpSelf doSomething];
}];
из документации копируется следующее:
блок формирует сильную ссылку на переменные, которые он захватывает. Если вы используете
selfвнутри блока, блок формирует сильную ссылку кself, Так что еслиselfтакже имеет сильную ссылку на блоке (который обычно делает), сильные результаты цикла ссылки. Чтобы избежать цикла, вам нужно к создайте слабого (или__block) ссылка на себя вне блока, как в приведенном выше примере.
Я не понимаю, что значит слабая (или )'?
и
__block typeof(self) tmpSelf = self;
и
__weak typeof(self) tmpSelf = self;
точно так же здесь?
я нашел еще один кусок в документе:
Примечание: В среде сбора мусора, если вы применяете оба
__weakи__blockмодификаторы к переменной, затем блок не будет гарантировать, что он остался жив.
Итак, я совершенно озадачен.
3 ответа:
из документов о _ _ block
__блочные переменные живут в хранилище, которое совместно используется между лексической областью переменной и всеми блоками и копиями блоков, объявленными или созданными в лексической области переменной. Таким образом, хранилище переживет разрушение кадра стека, если какие-либо копии блоков, объявленных в кадре, выживут за пределами конца кадра (например, будучи помещенными в очередь где-то для последующего выполнения). Несколько блоков в данном лексическая область может одновременно использовать общую переменную.
из документов о _ _ weak
__weak указывает ссылку, которая не поддерживает жизнь объекта ссылки. Слабая ссылка имеет значение nil, когда нет сильных ссылок на объект.
Так что технически это разные вещи. __block-это остановить копирование переменной из внешней области в область блока. __weak-это самоограничение слабых указатель.
обратите внимание, что я сказал технически, потому что для вашего случая они будут делать (почти) то же самое. Единственное различие заключается в том, используете ли вы ARC или нет. Если ваш проект использует ARC и предназначен только для iOS4.3 и выше, используйте __weak. Он гарантирует, что ссылка установлена в ноль, если глобальная ссылка на область каким-то образом освобождается. Если ваш проект не использует ARC или предназначен для более старых версий ОС, используйте __block.
здесь есть тонкая разница, убедитесь, что вы понимаете оно.
редактировать: еще один кусочек головоломки-это __небезопасных_ - носителя. Этот модификатор почти такой же, как __слабый, но для среды выполнения до 4.3. Однако он не установлен на ноль и может оставить вас с висячими указателями.
в режиме ручной подсчет ссылок, __идентификатор блока х; имеет эффект не сохраняя х. В режиме дуги, __идентификатор блока х; значения по умолчанию для сохранения х (как и все остальные значения). Чтобы получить ручное поведение режима подсчета ссылок в ARC, вы можете использовать __unsafe_unretained __block id x;. Однако, как следует из названия __unsafe_unretained, наличие нераспределенной переменной опасно (потому что она может болтаться) и поэтому не рекомендуется. Два лучших варианта-либо использовать _ _ weak (если вы не нужно поддерживать iOS 4 или OS X v10.6) или установить значение __block равным нулю, чтобы прервать цикл сохранения.