Мне интересно, каковы рекомендуемые способы обработки ситуаций, когда в управляемом памяти коде объект не принадлежал какому-либо конкретному владельцу, то есть объекты высвобождали себя. Одним из таких примеров может быть подкласс NSWindowController, который конфигурирует, отображает и управляет вводом и выводом одного окна. Объект контроллера отображает окно и в какой-то момент освобождает себя позже (обычно, когда окно или лист, которым он управляет, закрыто). AppKit также предоставляет несколько примеров: NSAnimation сохраняет себя в startAnimation и освобождает себя, когда анимация завершена. Другим примером является NSWindow, который можно настроить на освобождение при закрытии.
При реализации этих «собственных» объектов я вижу по крайней мере три различных шаблона, безопасных для GC, но все они имеют некоторые недостатки.
а). Использование CFRetain / CFRelease.
Самостоятельный объект вызывает CFRetain для себя перед тем, как он начинает свою работу (например, в примере контроллера окна перед отображением окна). Затем он вызывает CFRelease () для себя, когда это будет сделано (например, в примере контроллера окна после закрытия окна).
Плюсы: пользователю объекта не нужно беспокоиться об управлении памятью.
Минусы: немного некрасиво, поскольку требует использования функций управления памятью, хотя мы используем GC в чистом коде ObjC. Если CFRelease () не вызывается, утечка может быть трудно обнаружить.
б). Избегание идиомы владения собственностью со статической структурой данных.
Объект добавляет себя в структуру данных (например, статический изменяемый массив) перед тем, как он начинает свою работу, и удаляет себя оттуда, когда это сделано.
Плюсы: пользователю объекта не нужно беспокоиться об управлении памятью. Нет вызовов функций управления памятью. Объекты имеют явного владельца. Потенциальные утечки легко обнаружить.
Минусы: блокировка необходима, если объекты могут быть созданы из разных потоков. Дополнительная структура данных.
с). Избегайте идиомы владения собой, требуя, чтобы пользователь объекта сохранил ссылку на объект (например, в ивар).
Плюсы: нет вызовов функциям управления памятью. Объекты имеют явного владельца.
Минусы: пользователь объекта должен сохранять ссылку, даже если ему больше не нужен объект. Extra ivars.
Какой шаблон вы бы использовали для обработки этих случаев?