当我绑定到多级关键路径时,例如objectValue.person.photo
,当人员更改时,仅当照片发生更改时,它才会更新。这似乎是一个问题,只有路径中的最后一个键被观察到变化。
是否可以观察多个级别的绑定?例如,在SproutCore中,如果在路径中放置一个星号,则会在其后面的所有内容进行更改(objectValue*person.photo
)。
答案 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中非叶节点键的更改)。 objectValue
或person
中的对象实现中存在一些缺陷并阻止其工作。我会看那里。
另请注意,如果其中一个是集合,则观察集合与观察集合中的所有对象不同。有关详细信息,请参阅this page。
PS:是的,我知道这个例子会泄漏内存。您可以为自己设想相关的-dealloc
方法。