Как это предотвращает циклы сохранения блока?

Я видел решение для предотвращения циклов сохранения блока здесь

Но у меня возникают проблемы, когда я пытаюсь понять, почему и как это работает.

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

Скажем, например, что self - это 0x123. Тогда Слабый сам также указывает на 0x123. Тогда strongSelf будет установлен в 0x123 внутри блока.
Разве это не сделает цикл сохранения?(Self имеет сильную ссылку на block, а strongSelf имеет сильную ссылку на self)

2 ответа

Внутри блока создана сильная ссылка. Разве это не воссоздает цикл сохранения, который мы пытались предотвратить в первую очередь?

Да, но только временно. когда strongSelf инициализируется, он образует сильную ссылку на текущий weakSelf значение. (Или ноль, если этот объект был освобожден.) Как только блок завершит работу, эта (локальная) сильная ссылка будет освобождена, нарушая цикл.

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

Скажем, например, что self - это 0x123. Тогда Слабый сам также указывает на 0x123. Тогда strongSelf будет установлен в 0x123 внутри блока. Разве это не сделало бы цикл сохранения?

Вообще-то, нет; не все они указывают прямо на одно и то же. Дело в том, что слабая ссылка ARC действительно (за кадром) вставляет дополнительный объект в микс. Давайте назовем это блокнотом. Это создает иллюзию, что мы указываем на один и тот же объект, но на самом деле мы указываем через объект блокнота, который не сохраняет то, на что он указывает. Вот как работают слабые ссылки ARC (также известные как обнуление слабых ссылок); они включают в себя специальные дополнительные промежуточные объекты блокнота, которые могут быть сохранены без сохранения самих себя, тем самым разрывая цепь.

В цикле сохранения у A есть удержание на B, а у B есть удержание на A. Каждый помещает релиз в свой собственный. deallocНо этот момент никогда не наступит.

В ситуации блока A self и B это блок. self по какой-либо причине он удерживает блокировку (часто довольно неясную, связанную с копированием, наблюдателями и т. д.; это не всегда происходит, и на самом деле это происходит гораздо реже, чем кажется большинству людей), Блок положить удержание на self просто в силу того факта, что это закрытие и self упоминается в блоке.

Но, выполняя слабо-сильный танец, мы предотвращаем это. Что проходит в блок weakself, который на самом деле является ссылкой через объект блокнота. Блок может сохранить это, но он, в свою очередь, не сохраняет self, Следовательно, нет удерживающего цикла.

Другие вопросы по тегам