У меня была проблема с реализацией привязок для моего собственного подкласса NSView. Он работает, но есть проблемы с циклами сохранения при привязке к File Owner из файла nib. Немного поучившись, я обнаружил, что Apple имела такую же проблему несколько лет назад, но исправила ее каким-то магическим недокументированным классом (NSAutounbinder).
Здесь обсуждается проблема сохранения цикла http://www.cocoabuilder.com/archive/message/cocoa/2004/6/12/109600. Обходной путь состоит в том, чтобы развязать все привязки, прежде чем оконный контроллер будет выпущен, а не до того, как он будет освобожден, в таком месте, как windowWillClose:. Это кажется ненужным взломом для меня.
Мой вопрос заключается в следующем: есть ли способ сделать пользовательские привязки, которые работают так же хорошо, как те, которые сделаны Apple, без использования недокументированных функций? Я иду об этом неправильно?
ОБНОВЛЕНИЕ 2: Я нашел решение, которое позволяет вручную реализовывать привязки для работы точно так же, как привязки Apple. Он использует недокументированный класс NSAutounbinder, фактически не используя недокументированные функции. Я опубликую решение позже сегодня.
UPDATE: Я пробовал использовать exposeBinding:
, и, похоже, это не имеет значения. Однако реализация NSObject
работы bind:toObject:withKeyPath:options:
работает. Он пропагандирует изменения от bindee до связующего (то есть от модели/контроллера для просмотра), но не работает обратным образом. Кроме того, хотя наблюдатель, очевидно, наблюдается, observeValueForKeyPath:ofObject:change:context:
никогда не срабатывает.
Пример здесь: http://www.tomdalling.com/wp-content/BindingsTest.zip
Документация Apple указывает, что на самом деле вам необходимо переопределить bind:toObject:withKeyPath:options:
для реализации ручных привязок. См. Здесь: http://developer.apple.com/documentation/Cocoa/Conceptual/CocoaBindings/Concepts/HowDoBindingsWork.html
ПРИМЕЧАНИЕ: Я исследовал, как работает недокументированный NSAutounbinder, и вот что я знаю.
Когда привязка создается в NSWindowController, связанный объект на самом деле является NSAutounbinder, который получен от NSWindowController с - [NSWindowController _autounbinder]. NSAutounbinder - не сохраняющий прокси-сервер для объекта NSWindowController. Он не удерживается, чтобы избежать проблемы с циклом сохранения.
Когда - вызывается [NSWindowController release] и сохраняетCount == 1, NSAutounbinder распаковывает все привязки для себя. Это гарантирует, что нет никаких оборванных указателей на объект до того, как он будет освобожден.