Собственные объекты в Objective-C Сборка мусора - PullRequest
6 голосов
/ 28 октября 2008

Мне интересно, каковы рекомендуемые способы обработки ситуаций, когда в управляемом памяти коде объект не принадлежал какому-либо конкретному владельцу, то есть объекты высвобождали себя. Одним из таких примеров может быть подкласс NSWindowController, который конфигурирует, отображает и управляет вводом и выводом одного окна. Объект контроллера отображает окно и в какой-то момент освобождает себя позже (обычно, когда окно или лист, которым он управляет, закрыто). AppKit также предоставляет несколько примеров: NSAnimation сохраняет себя в startAnimation и освобождает себя, когда анимация завершена. Другим примером является NSWindow, который можно настроить на освобождение при закрытии.

При реализации этих «собственных» объектов я вижу по крайней мере три различных шаблона, безопасных для GC, но все они имеют некоторые недостатки.

а). Использование CFRetain / CFRelease.

Самостоятельный объект вызывает CFRetain для себя перед тем, как он начинает свою работу (например, в примере контроллера окна перед отображением окна). Затем он вызывает CFRelease () для себя, когда это будет сделано (например, в примере контроллера окна после закрытия окна).

Плюсы: пользователю объекта не нужно беспокоиться об управлении памятью.
Минусы: немного некрасиво, поскольку требует использования функций управления памятью, хотя мы используем GC в чистом коде ObjC. Если CFRelease () не вызывается, утечка может быть трудно обнаружить.

б). Избегание идиомы владения собственностью со статической структурой данных.

Объект добавляет себя в структуру данных (например, статический изменяемый массив) перед тем, как он начинает свою работу, и удаляет себя оттуда, когда это сделано.

Плюсы: пользователю объекта не нужно беспокоиться об управлении памятью. Нет вызовов функций управления памятью. Объекты имеют явного владельца. Потенциальные утечки легко обнаружить.
Минусы: блокировка необходима, если объекты могут быть созданы из разных потоков. Дополнительная структура данных.

с). Избегайте идиомы владения собой, требуя, чтобы пользователь объекта сохранил ссылку на объект (например, в ивар).

Плюсы: нет вызовов функциям управления памятью. Объекты имеют явного владельца.
Минусы: пользователь объекта должен сохранять ссылку, даже если ему больше не нужен объект. Extra ivars.

Какой шаблон вы бы использовали для обработки этих случаев?

Ответы [ 2 ]

5 голосов
/ 28 октября 2008

Для а) более идиоматическая альтернатива CFRetain(foo) / CFRelease(foo) равна [[NSGarbageCollector defaultCollector] disableCollectorForPointer:foo] / [[NSGarbageCollector defaultCollector] enableCollectorForPointer:foo].

2 голосов
/ 28 октября 2008

Apple рекомендует (с), но мне нравится звук (б). Статическая структура данных позволяет скрыть детали GC от пользователя API, избегая при этом погружения в уровень CFRetain / CFRelease. Как вы заявляете, это также облегчает отладку и модульное тестирование; если объект все еще ссылается на статическую структуру данных после того, как он завершил свою задачу, вы знаете, что есть ошибка.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...