如果您的绑定在objectValue.person 更改时没有更新,那么这通常意味着objectValue 中的任何对象都不符合键person. 的键值观察与正确实现的对象,非叶突变沿着 keyPath 工作正常。例如,从基本的非文档 Cocoa 应用程序模板开始,我制作了以下示例:
标题:
@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 中的哪个级别,我们都会得到适当的更新。
简而言之,绑定按照您希望的方式工作(即,它们会根据复合 keyPath 中的非叶节点键的更改进行更新)。在objectValue 或person 中的对象的实现中存在缺陷并阻止了它的工作。我会去那里看看。
另外请注意,如果这些事物之一是集合,那么观察集合与观察集合中的所有对象不同。有关更多信息,请参阅this page。
PS:是的,我知道这个例子会泄漏内存。你可以自己想象相关的-dealloc方法。