Роль -supportsWeakPointers

Apple недавно опубликовала Переход к ARC Release Notes , документ, который объясняет ARC и решает некоторые проблемы преобразования кода, отличного от ARC, в ARC. В этих примечаниях они упоминают следующее:

Если вы [sic] обнаружите, что должны реализовать собственные методы сохранения или выпуска, вы также должны реализовать в своем классе следующий метод:

 - (BOOL) supportsWeakPointers { вернуть НЕТ; } 
 

Этот метод предотвратит формирование слабых указателей на ваши объекты. Мы настоятельно рекомендуем вам найти решение, которое не требует реализации ваших собственных методов сохранения и выпуска вместо этого.

Рассмотрим следующий сценарий:

  1. Объявите класс MyClass и реализуйте -supportsWeakPointers как возвращающий NO. Скажите Xcode скомпилировать соответствующий файл реализации с помощью -fno-objc-arc. Для удобства объявите класс как NS_AUTOMATED_REFCOUNT_WEAK_UNAVAILABLE и переопределите -release и -retain.

  2. В MainMenu.xib поместите объект верхнего уровня типа MyClass.

  3. В делегате приложения укажите слабое свойство IBOutlet для экземпляра MyClass:

     @property (weak) IBOutlet MyClass * myObject; 
     

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

Мой вопрос двоякий тройной :

  1. Почему -supportsWeakPointers является методом экземпляра, а не методом класса? Есть ли случай, когда у класса могут быть экземпляры, которые различаются по разрешению слабых ссылок?

  2. -supportsWeakPointers никогда не отправляются в экземпляр MyClass, созданный при загрузке файла пера; Почему? Я проверил это, поместив в него NSLog () и добавив символическую точку останова в Xcode. Кроме того, при запуске программы я никогда не получаю сообщение

     не могу сформировать слабую ссылку на экземпляр (0x ???) класса MyClass 
     

    .

  3. Объект пера верхнего уровня типа MyClass никогда не должен освобождаться во время выполнения программы, потому что моя программа никогда не освобождает его. Однако соответствующий слабый выход равен нулю после загрузки файла пера; Почему? Изменение свойства выхода на сильное приведет к тому, что объект будет отличаться от нуля, но в этом нет необходимости. На самом деле не бывает; извиняюсь. Я тестировал версию, которая присваивала новый объект, который на самом деле не использовался, поэтому ARC правильно присвоил свойству nil .

Пример проекта, воспроизводящего эту ошибку, доступен здесь .

Я использую Xcode 4.2 с Apple LLVM Compiler 3.0 в операционной системе Mac OS X v10.7.2.

14
задан 17 October 2011 в 04:56
поделиться