我有一个 NSView 子类,它具有我想要可绑定的属性。我在子类中实现了以下内容:
我的视图.h:
@property (readwrite, retain) NSArray *representedObjects;
我的视图.m:
@synthesize representedObjects;
+(void)initialize
{
[self exposeBinding: @"representedObjects"];
}
-(void)bind:(NSString *)binding toObject:(id)observableController withKeyPath:(NSString *)keyPath options:(NSDictionary *)options
{
if ([binding isEqualToString:@"representedObjects"]) {
[observableController addObserver: self forKeyPath:@"arrangedObjects" options:NSKeyValueChangeNewKey context:nil];
} else {
[super bind: binding toObject:observableController withKeyPath:keyPath options: options];
}
}
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
if ([keyPath isEqualToString:@"arrangedObjects"]) {
[self setRepresentedObjects: [object arrangedObjects]];
}
}
然后,我在以下位置创建与 arrayController 的绑定-[AppController awakeFromNib]
:
[myView bind:@"representedObjects" toObject:arrayController withKeyPath:@"arrangedObjects" options: nil];
这是实现绑定的正确方法吗?它涉及很多样板代码,这让我觉得我做错了什么。
我认为 NSObject 会自动实现我手动完成的操作,-bind:toObject:withKeyPath:options:
但事实并非如此。如果我注释掉我-bind:toObject:withKeyPath:options:
的 setRepresentedObjects 方法,则永远不会被调用。
附加信息:我进行了更多调查并得出结论,我的原始方法是正确的,您确实必须 override -bind:toObject:withKeyPath:options:
。这是 Cocoa Bindings Programming Topics 中的一段话:Bindings 是如何工作的?:
在其 bind:toObject:withKeyPath:options: 方法中,对象必须至少执行以下操作:
- 确定正在设置的绑定
- 使用什么键路径和什么选项记录它绑定到的对象
- 注册为绑定对象的 keypath 的观察者,以便接收更改通知
清单 2 中的代码示例显示了操纵杆的 bind:toObject:withKeyPath:options: 方法的部分实现,该方法仅处理角度绑定。
清单 2 Joystick 类的 bind:toObject:withKeyPath:options 方法的部分实现:
static void *AngleBindingContext = (void *)@"JoystickAngle"; - (void)bind:(NSString *)binding toObject:(id)observableObject withKeyPath:(NSString *)keyPath options:(NSDictionary *)options { // Observe the observableObject for changes -- note, pass binding identifier // as the context, so you get that back in observeValueForKeyPath:... // This way you can easily determine what needs to be updated. if ([binding isEqualToString:@"angle"]) { [observableObject addObserver:self forKeyPath:keyPath options:0 context:AngleBindingContext]; // Register what object and what keypath are // associated with this binding observedObjectForAngle = [observableObject retain]; observedKeyPathForAngle = [keyPath copy]; // Record the value transformer, if there is one angleValueTransformer = nil; NSString *vtName = [options objectForKey:@"NSValueTransformerName"]; if (vtName != nil) { angleValueTransformer = [NSValueTransformer valueTransformerForName:vtName]; } } // Implementation continues...
这清楚地表明 Joystick 类(它是一个 NSView 子类)需要覆盖-bind:toObject:withKeyPath:options:
.
我觉得这很令人惊讶。我对这个结论持怀疑态度,因为我没有发现其他代码示例可以做到这一点。然而,正如苹果官方文档所说我应该超越-bind:toObject:withKeyPath:options:
我的结论,这是正确的方法。
如果有人能证明我错了,我会很高兴的!