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 };