Ответ 1
В LLVM Compiler 3.0 представлены четыре новых квалификатора собственности: __strong
, __autoreleasing
, __unsafe_unretained
и __weak
. Первые три доступны даже вне ARC, согласно спецификация.
Как указывает Джошуа, по умолчанию все указатели подразумеваются как __strong
под ARC. Это означает, что когда объект присваивается этому указателю, он сохраняется до тех пор, пока этот указатель ссылается на него. Это прекрасно для большинства вещей, но это открывает возможность для сохранения циклов, как я опишу в своем ответе здесь. Например, если у вас есть объект, который содержит другой объект в качестве переменной экземпляра, но второй объект имеет прочную ссылку на первую в качестве своего делегата, эти два объекта никогда не будут выпущены.
Именно по этой причине существуют квалификаторы __unsafe_unretained
и __weak
. Их наиболее распространенное использование - для делегатов, где вы должны определить свойство для этого делегата с атрибутом weak
или unsafe_unretained
(assign
is эффективно unsafe_unretained
), а затем сопоставить это, пометив соответствующую переменную экземпляра с помощью __weak
или __unsafe_unretained
. Это означает, что переменная экземпляра делегата будет по-прежнему указывать на первый объект, но это не приведет к тому, что этот объект будет сохранен, тем самым нарушая цикл сохранения и позволяя освобождать оба объекта.
Помимо делегатов, полезно разбить любые другие циклы сохранения, которые могут быть сформированы в вашем коде. Полезно, что инструмент "Утечки" теперь включает в себя представление "Циклы", в котором показаны циклы сохранения, которые он обнаруживает в вашем приложении графически.
Оба __unsafe_unretained
и __weak
предотвращают сохранение объектов, но несколько по-разному. Для __weak
указатель на объект преобразуется в nil
при освобождении объекта, на который указывает, что очень безопасно. Как следует из его названия, __unsafe_unretained
будет продолжать указывать на память, где был объект, даже после его освобождения. Это может привести к сбоям из-за доступа к этому освобожденному объекту.
Зачем вам когда-либо использовать __unsafe_unretained
? К сожалению, __weak
поддерживается только для iOS 5.0 и Lion в качестве целей развертывания. Если вы хотите настроить таргетинг на iOS 4.0 и Snow Leopard, вы должны использовать квалификатор __unsafe_unretained
или использовать что-то вроде Mike Ash MAZeroingWeakRef.