Почему NSViewController не связывает представленный объект?

Вкратце: я привязываю NSTextField к владельцу файла (контроллеру представления) и пути к ключу модели representedObject.firstName, но редактирование текстового поля не меняет firstName.

Вот более подробная информация. У меня есть простая программа, которая ничего не делает, кроме как создает экземпляр Thing (простой класс с некоторыми свойствами) и ThingViewController. Контроллер имеет связанный .xib с простым пользовательским интерфейсом — пара текстовых полей для привязки к свойствам Thing.

@interface Thing : NSObject
@property (nonatomic, strong) NSString *firstName;
@property (nonatomic, strong) NSString *lastName;
@property (nonatomic) BOOL someBool;
@end

И в делегате приложения...

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    NSView *cv = self.window.contentView;
    ThingViewController *vc = [[ThingViewController alloc] 
                                 initWithNibName:@"ThingViewController" bundle:nil];
    theThing = [Thing new];
    theThing.firstName = @"Rob";
    vc.representedObject = theThing;   
    [cv addSubview:vc.view];
}

ThingViewController.xib прост:

введите здесь описание изображения

А вот привязка для этого первого текстового поля:

введите здесь описание изображения

Когда я запускаю, в текстовом поле отображается «Роб», поэтому он работает в этом направлении, но затем, когда я редактирую текстовое поле, свойство firstName для theThing не изменяется.

Что я делаю неправильно?

Изменить. Вот ссылка на заархивированный файл проекта для приведенного выше кода: https://drive.google.com/file/d/0B2NHW8y0ZrBwWjNzbGszaDQzQ1U/edit?usp=sharing


person Rob N    schedule 22.03.2014    source источник
comment
Попробуйте постоянно обновлять значение? Мне нужно было в основном контексте данных с полем токена. Правки пользователя не были немедленно переданы в модель.   -  person stevesliva    schedule 22.03.2014
comment
Я пробовал, но не вижу изменений в поведении.   -  person Rob N    schedule 22.03.2014


Ответы (1)


Ничто не строго ссылается на ваш контроллер представления (ThingViewController), кроме локальной переменной в -applicationDidFinishLaunching:. Как только это выходит за рамки, контроллер представления освобождается и освобождается. Само представление все еще существует, так как оно является подвидом содержимого вашего окна.

Как только ваш контроллер представления освобождается/уходит, текстовое поле не имеет обратной связи с объектом Thing, поэтому оно фактически вызывает [nil setValue:@"Новое имя" forKeyPath:@"representedObject.firstName"].

Добавьте сильную ссылку на ваш контроллер представления (например, переменную экземпляра вашего делегата приложения) и повторите попытку.

@implementation AppDelegate {
    Thing *theThing;
    ThingViewController *vc;
}

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    NSView *cv = self.window.contentView;
    vc = [[ThingViewController alloc] initWithNibName:@"ThingViewController" bundle:nil];
    theThing = [Thing new];
    theThing.firstName = @"Rob";
    vc.representedObject = theThing;

    [cv addSubview:vc.view];
}
person ondmike    schedule 22.03.2014
comment
Это сделало это. Я до сих пор не переучился из мира JVM и сборки мусора. - person Rob N; 22.03.2014