2

我有一个具有不同实体和属性的核心数据 Mac 应用程序...其中一个属性绑定到 NSButton 复选框...

这是我的问题:如果我用鼠标单击按钮,我可以看到它的状态发生变化(例如从未选中更改为选中),并且绑定属性的状态保存到数据核心,因为如果我关闭并重新打开应用程序,该按钮仍处于选中状态...

但 ...

如果我以编程方式更改此按钮的状态,我仍然可以看到它的状态更改(相同的示例,从未选中更改为选中),但绑定属性的状态未保存到数据核心,如果我关闭并重新打开应用程序,按钮回到未选中状态!

有任何想法吗 ?

编辑

好吧,我会尽力解释(对不起我的英语不好)......</p>

我必须对这个名为 Adherents 的实体的一些值进行一些操作和验证(例如,如果 date1> date2 则选中 checkbox1,如果选中 checkbox2,则无论日期比较如何,都会选中 checkbox1 ...</p>

我首先指出了一个解决方案,在“NSManagedObject 子类文件 Adherents.m

- (void)awakeFromFetch{

 [super awakeFromFetch];


    // Controle de la cotisation
    aujourdhui = [NSDate date];
    finCotisation = [NSDate dateWithString:[dateCotisation description]];
    controle = [aujourdhui compare:finCotisation];
   if(controle == NSOrderedAscending)
   {
       self.cotisation = [NSNumber numberWithBool:1];
   }
    else if(controle == NSOrderedDescending)
    {
       if ([self.membreHonneur boolValue] == 0)
       {
            self.cotisation = [NSNumber numberWithBool:0];
        }
      else if ([self.membreHonneur boolValue] == 1)
       {
            self.cotisation = [NSNumber numberWithBool:1];
       }
    }
}

像那样,该操作仅在应用程序启动时发生,这很好但还不够……要做到这一点“在路上”(就在用户通过 NSDatePicker 输入或更改日期之后)我建立的最佳解决方案是检查何时日期选择器由用户编辑......似乎我只能在 AppDelegate.m 文件中执行此操作(尝试在 Adherents.h 中声明“IBOutlet NSDatePicker *champDate;”,但是后来,我无法使用复选框连接插座在Interface Builder ...)中,我似乎也无法从那里访问和操作实体值(“self.cotisation”在AppDelegate.m中使用时带来了一个未知属性,我找不到如何声明它在 AppDelegate.h 中正确)。

所以,我的解决方案是在 AppDelegate 中进行这些操作,比较 NSDatePicker 的值并作用于 NSButton 复选框状态……

- (void)awakeFromNib {

    [champDate setTarget:self];
    [champDate setAction:@selector(checkDate:)];

}

-(void)checkDate:(id)object {
   finCotisation = [NSDate dateWithNaturalLanguageString:[champDate stringValue]];
   aujourdhui = [NSDate date];
   NSComparisonResult controle = [aujourdhui compare:finCotisation];
    if(controle == NSOrderedAscending){
        [bouttonCotisation setState:TRUE];
    }
    else if(controle == NSOrderedDescending){
        [bouttonCotisation setState:FALSE];
   }
}

但是,当这样做时,绑定失败......所以,我必须同时做:监控 NSDatePicker 并以编程方式更改我的 AppDelegate.m 中的复选框状态,并且还使用 Adherents.m 中的 AwakeFromFetch 检查和更改实体值,我认为这是一个当一切都绑定时,真是胡说八道^^

4

1 回答 1

3

我不确定我是否了解您的问题的具体情况,但收集了这么多:

  • 从外部看到的数据模型对象具有以下属性
    • 两个日期值
    • 一个布尔值
    • 第二个布尔值,应根据其他三个值具有不同的值
  • 您只更新方法中的依赖值awakeFromFetch,因此在运行时更改数据时不会更新它,因此您在 AppDelegate 中手动更改复选框。

我发现这种方法有两个问题:

  1. 使用绑定时,您应该只更改模型数据以更新 UI,而不是直接调用 UI 元素的设置器。
  2. 如果您有一个完全依赖于其他属性的属性,请不要单独保存它(缓存原因除外,但这会使它更加复杂)。只需即时计算即可。

我假设您的模型类如下所示:

@interface
@property (strong) NSDate *date1;
@property (strong) NSDate *date2;
@property (assign BOOL someBool;
@end

现在我们以同样的方式声明将依赖属性添加到头文件中:

// readonly because it cannot be changed directly, only the values it depends on can be changed
@property (assign, readonly) BOOL dependentBool;

但是对于这个属性,我们自己在@implementation 中实现getter:

-(BOOL)dependentBool
{
    if (NSOrderedAscending = [self.date1 compare:self.date2])
        return YES;

    if (self.someBool)
        return YES;

    return NO;
}

这样,每当有人检查dependentBool 属性时,它都会返回正确的结果。您现在可以将您的复选框绑定到dependentBool。但是,如果您更改任何值,它取决于复选框将不会更新,因为它不知道值已更改。为了解决这个问题,我们将以下方法添加到模型类实现中:

+(NSSet *)keyPathsForValuesAffectingDependentBool
{
    return [NSSet setWithArray:@[@"date1", @"date2", @"someBool"]];
}

这告诉任何观察该dependentBool属性的人(就像复选框在绑定到该属性时所做的那样)它依赖于这些键路径,因此也应该观察这些键路径。

这样,您只需更改date1例如的值,绑定到的任何视图dependentBool都将相应更改。

注意:要使其正常工作,您必须通过它们的设置器([myModelObject setDate1:date]或)更改属性的值myModelObject.date1 = date,而self.date1 = date不是直接更改实例变量(_date1 = date)。

我希望你能根据你的需要调整这个例子。

于 2013-01-08T11:56:27.030 回答