【问题标题】:Multilevel cocoa bindings多级可可绑定
【发布时间】:2012-01-12 02:33:41
【问题描述】:

当我绑定到多级键路径时,比如objectValue.person.photo,它不会在人员更改时更新,只有在照片更改时才会更新。这似乎是一个问题,只有路径中的最后一个键被观察以进行更改。

是否可以观察多个级别的绑定?例如,在 SproutCore 中,如果您在路径中放置一个星号,则会观察到它之后的所有内容是否有变化 (objectValue*person.photo)。

【问题讨论】:

    标签: cocoa cocoa-bindings


    【解决方案1】:

    如果您的绑定在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 中的非叶节点键的更改进行更新)。在objectValueperson 中的对象的实现中存在缺陷并阻止了它的工作。我会去那里看看。

    另外请注意,如果这些事物之一是集合,那么观察集合与观察集合中的所有对象不同。有关更多信息,请参阅this page

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多