Cocoa:绑定到复合对象并观察子属性

时间:2013-02-01 12:36:25

标签: objective-c cocoa cocoa-bindings key-value-observing

是否可以绑定到自定义对象并在该对象的特定属性发生更改时收到通知?

示例:

每个销售代表对象都有一个销售统计对象的引用,其中包含汽车和卡车销售的统计信息。自定义NSView用于在一个图形中绘制汽车和卡车销售。

自定义视图需要访问完整的统计信息对象,因此我将其绑定到salesRep.salesStats

但是,当我更改carSales属性时,我需要一种方法来更新视图。目前它没有更新,因为它绑定到父对象。

我想避免为每种销售类型建立绑定(这只是一个例子,我的具体情况更复杂)。

@interface SBSalesRep : NSObject {

@property (strong) SBSalesStatistics *salesStats;
}

@interface SBSalesStatistics : NSObject
{
@property (assign) NSInteger carSales;
@property (assing) NSInteger truckSales;
}

@interface SBProgressView : NSView
{
@property (strong) SBSalesStatistics *statsToDisplay;
}

// Setup
SBSalesRep *salesRep = [SBSalesRep new];

// Bind to stats object, because we need car and tuck sales:
[progressView bind:@"statsToDisplay" 
          toObject:salesRep 
       withKeyPath:@"salesStats"  // How to get notified of property changes here?
           options:nil];

// This needs to trigger an update in the statistics view
salesRep.salesStats.carSales = 50;

// I tried this, but it does not work:
[salesRep willChangeValueForKey:@"salesStatistics"];
salesRep.salesStats.carSales = 50;
[salesRep didChangeValueForKey:@"salesStatistics"];

1 个答案:

答案 0 :(得分:1)

你说:

// I tried this, but it does not work:
[salesRep willChangeValueForKey:@"salesStatistics"];
salesRep.salesStats.carSales = 50;
[salesRep didChangeValueForKey:@"salesStatistics"];

我的猜测是,这不起作用,因为您通知的密钥是salesStatistics,但您绑定的密钥是salesStats。如果这些键是相同的,我希望这种方法可以工作。

除此之外,更好的方法可能是添加这样的依赖:

@implementation SBSalesRep

+ (NSSet *) keyPathsForValuesAffectingSalesStats
{
    return [NSSet setWithObjects: @"salesStats.carSales", @"salesStats.truckSales", nil];
}

@end

这将导致键salesStats的任何观察(绑定或其他)也隐式观察salesStats.carSalessalesStats.truckSales,并且应该达到预期的效果,而不必手动通知{ {1}}。

相关问题