Как NSViewController предотвращает утечку памяти привязок? [есть образец приложения] - PullRequest
0 голосов
/ 17 января 2010

Я пытаюсь реализовать свою собственную версию NSViewController (для обратной совместимости), и у меня возникла проблема с привязками: поскольку привязки сохраняют свою цель, у меня появляется круг сохранения при каждой привязке через владельца файла.

Так что я решил просто явно удалить свой вид из его суперпредставления и освободить объекты верхнего уровня, и это позаботится о привязках, потому что мой контроллер больше не удерживает представления, поэтому они освобождают меня и я могу уйти. Но по какой-то причине мой контроллер представления все еще не выпущен. Вот пример приложения, показывающего проблему:

http://dl.dropbox.com/u/34351/BindingsLeak.zip

Создайте его, запустите и нажмите Cmd-K («Создать Nib» в меню «Редактировать»), чтобы загрузить NIB в пустое окно. Нажмите Cmd-K еще раз, чтобы освободить первый контроллер представления (TestNibOwner) и загрузить новый. Однако старый контроллер представления никогда не освобождается.

Удалите привязку «значение» на флажок, и он будет выпущен просто отлично.

Если вы установите точки останова в переопределениях release / retain / autorelease, вы увидите, что _NSBindingInfo сохраняет TestNibOwner, но никогда не освобождает его в случае утечки.

Кто-нибудь знает, как это исправить?

Ответы [ 3 ]

2 голосов
/ 17 января 2010

Проведя небольшое исследование с дампом классов и друзьями, похоже, что у Apple есть закрытый класс NSAutounbinder, который занимается этой грязной работой для таких классов, как NSViewController и NSWindowController. Правда, не могу сказать, как это работает или как его воспроизвести.

Итак, я не могу ответить на ваш вопрос о том, как предотвратить возникновение цикла сохранения для произвольных привязок в загруженном наконечнике, но, возможно, утешительно знать, что Apple обманывает, и вы не упускаете ничего очевидного , : -)

1 голос
/ 17 января 2010

Одна вещь, которую я сделал для той же проблемы, - это создание прокси NSObjectController внутри моего пера. Мой NSViewController-подобный класс имеет указатель на этот прокси, и все привязки связаны через него. Когда я хочу очистить контроллер представления, я тогда делаю [selfProxy setContent: nil] на контроллере объекта и освобождаю контроллер представления. В этом случае прокси-сервер NSObjectController в этом случае действует как автоматическое связывание.

Это больше руководство, и вы не можете просто отпустить представление, но это решает проблему сохранения.

Я бы посоветовал вам сделать это:

-(void) releaseTopLevelObjects
{
    // Unbind the object controller's content by setting it to nil.
    [selfProxy setContent:nil];

    NSLog( @"topLevelObjects = %@", topLevelObjects );
    [topLevelObjects release];
    topLevelObjects = nil;
}

В вашем перо привязки будут проходить через путь, подобный:

selfProxy.content.representedObject.fooValue
0 голосов
/ 17 января 2010

Когда вы удаляете свое представление из его суперпредставления, вы также отправляете ему еще одно -релизное сообщение? Он был создан путем разархивирования из пера, верно?

...