多级可可绑定

时间:2012-01-12 02:33:41

标签: cocoa cocoa-bindings

当我绑定到多级关键路径时,例如objectValue.person.photo,当人员更改时,仅当照片发生更改时,它才会更新。这似乎是一个问题,只有路径中的最后一个键被观察到变化。

是否可以观察多个级别的绑定?例如,在SproutCore中,如果在路径中放置一个星号,则会在其后面的所有内容进行更改(objectValue*person.photo)。

1 个答案:

答案 0 :(得分:2)

如果更改objectValue.person时您的绑定未更新,那么这通常意味着objectValue中的任何对象都不符合键值person.的键值观察正确实施对象,沿keyPath的非叶子突变工作正常。例如,从基础非文档Cocoa Application模板开始,我编写了以下示例:

部首:

@interface Person : NSObject
@property (copy) NSString* name;
@end

@interface Car : NSObject
@property (retain) Person* driver;
@end

@interface SOAppDelegate : NSObject <NSApplicationDelegate>

@property (assign) IBOutlet NSWindow *window;
@property (retain) Car* car;

- (IBAction)replaceCar:(id)sender;
- (IBAction)replaceDriver:(id)sender;
- (IBAction)changeName:(id)sender;

@end

实现:

@implementation Person
@synthesize name;
@end

@implementation Car
@synthesize driver;
@end

@implementation SOAppDelegate
@synthesize car = _car;
@synthesize window = _window;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
    Person* person = [[[Person alloc] init] autorelease];
    person.name = @"Default Name";
    Car* car = [[[Car alloc] init] autorelease];
    car.driver = person;
    self.car = car;
}

- (IBAction)replaceCar:(id)sender
{
    Person* person = [[[Person alloc] init] autorelease];
    person.name = @"Replaced Car";
    Car* newCar = [[[Car alloc] init] autorelease];
    newCar.driver = person;    
    self.car = newCar;
}

- (IBAction)replaceDriver:(id)sender
{
    Person* person = [[[Person alloc] init] autorelease];
    person.name = @"Replaced Driver";    
    self.car.driver = person;
}

- (IBAction)changeName:(id)sender
{
    self.car.driver.name = @"Changed Name";
}

@end

然后在.xib中,我添加了三个按钮,调用每个IBActions并添加了一个标签,其value属性绑定到App Delegate,其keyPath为car.driver.name

按下任何按钮都会导致绑定标签更新,尽管事实上只有其中一个实际修改了绑定keyPath(car.driver.name)指向的确切值。使用标准的@synthesized属性免费提供KVO合规性,因此无论密钥路径的级别如何,我们都会获得适当的更新。

简而言之,绑定按照您希望的方式工作(即,它们会更新复合keyPath中非叶节点键的更改)。 objectValueperson中的对象实现中存在一些缺陷并阻止其工作。我会看那里。

另请注意,如果其中一个是集合,则观察集合与观察集合中的所有对象不同。有关详细信息,请参阅this page

PS:是的,我知道这个例子会泄漏内存。您可以为自己设想相关的-dealloc方法。