LLVM Compiler 3.0 вводит четыре новых классификаторов собственности: __strong
, __autoreleasing
, __unsafe_unretained
, и __weak
. Первые три доступны даже за пределами ARC, согласно спецификации .
Как указывает Джошуа, по умолчанию подразумевается, что все указатели находятся __strong
под ARC. Это означает, что когда объект назначается этому указателю, он сохраняется до тех пор, пока этот указатель ссылается на него. Это нормально для большинства вещей, но открывает возможность для сохранения циклов, как я описываю в своем ответе здесь . Например, если у вас есть объект, который содержит другой объект в качестве переменной экземпляра, но этот второй объект имеет сильную обратную связь с первым в качестве своего делегата, эти два объекта никогда не будут освобождены.
Именно по этой причине существуют квалификаторы __unsafe_unretained
и __weak
. Чаще всего они используются для делегатов, где вы определяете свойство для этого делегата с помощью атрибута weak
или unsafe_unretained
( assign
фактически unsafe_unretained
), а затем сопоставляете его, отмечая соответствующую переменную экземпляра с помощью __weak
или __unsafe_unretained
. Это означает, что переменная экземпляра делегата по-прежнему будет указывать на первый объект, но это не приведет к тому, что этот объект будет сохранен, тем самым прервав цикл сохранения и позволив освободить оба объекта.
Помимо делегатов, это полезно для разрыва любых других циклов сохранения, которые могут образоваться в вашем коде. К счастью, инструмент Leaks теперь включает представление Cycles, в котором графически отображаются циклы сохранения, обнаруженные в вашем приложении.
Оба __unsafe_unretained
и __weak
предотвращают задержку предметов, но несколько разными способами. Ведь __weak
указатель на объект будет преобразован в nil
при освобождении объекта, на который он указывает, что является очень безопасным поведением. Как следует из названия, __unsafe_unretained
будет продолжать указывать на память, в которой находился объект, даже после того, как он был освобожден. Это может привести к сбоям из-за доступа к этому освобожденному объекту.
Зачем __unsafe_unretained
тогда использовать ? К сожалению, в __weak
качестве целей развертывания поддерживается только iOS 5.0 и Lion. Если вы хотите вернуться к iOS 4.0 и Snow Leopard, вы должны использовать __unsafe_unretained
квалификатор или использовать что-то вроде MAZeroingWeakRef Майка Эша .
__unsafe_unretained
может быть полезно для определения массивовNSString
констант C и т.п., напримерNSString __unsafe_unretained *myStrings = { @"Foo", @"Bar", @"Baz", nil };