В чем разница между слабой и блочной ссылкой?
я читаю документацию 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 равным нулю, чтобы прервать цикл сохранения.