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