awakeFromFetch中的核心数据NSNotification导致崩溃

时间:2012-10-08 00:10:57

标签: core-data nsnotification

我确定之前有人看过这个,我可能会遗漏一些明显的东西...这是简短的概述:我有一个核心数据应用程序,它有Car和CarMileage,更准确地被认为是一次汽车之旅(Car>> CarMileage)。 CarMileage包含一些属性,包括里程(浮点数,行程长度)和forWork(BOOL)。我制作了一个自定义的CarMileage类,其中包括mileageForWork(浮点数,如果forWork = YES则返回里程,如果forWork = NO则返回0)。我还做了+ keyPathsForValuesAffectingMileageForWork返回里程和forWork的设置。现在我需要计算当年特定汽车的总里程百分比。

目前我在CarMileage:

- (float) mileageForWork {
    float mileageForWork;
    if ([self.forWork boolValue] == YES) {
        mileageForWork = [self.mileage floatValue];
    } else {
        mileageForWork = 0;
    }
    [[NSNotificationCenter defaultCenter] postNotificationName: @"mileageForWorkChanged" object:self];
    NSLog(@"send notification");
    return mileageForWork;
}

然后汽车有:

- (void) awakeFromFetch {
    [super awakeFromFetch];
    [self updatePercentMileageForWork];
    [[NSNotificationCenter defaultCenter] addObserver: self
                                             selector: @selector(updatePercentMileageForWork)
                                                 name: @"mileageForWorkChanged"
                                               object: nil];
    NSLog(@"awakeFromFetch");
}

- (void) awakeFromInsert {
    [super awakeFromInsert];
    [[NSNotificationCenter defaultCenter] addObserver: self
                                             selector: @selector(updatePercentMileageForWork)
                                                 name: @"mileageForWorkChanged"
                                               object: nil];
    NSLog(@"awakeFromInsert");
}

当加载自动保存的文件时,我会转到包含适用于Car和CarMileage的NSArrayController的Vehicles部分。日志显示“发送通知”,percentMileageForWork的值和“awakeFromFetch”,然后程序暂停,XCode中的线程选项卡弹出szone_malloc_should_clear,EXC_BAD_ACCESS代码= 2.

我完全不知道为什么会这样。我不太经常看到问题出在应该遵守通知的地方;毕竟,帖子会产生一个日志。任何想法为什么会崩溃?

编辑(10月14日) - 我试图将事物改为关键值观察模型,以便在CarMileage的-awakeFromInsert-awakeFromFetch中,该对象将Car添加为自身的观察者。这适用于提取的预期,但是当插入对象时,我的-updatePercentMileageForWork方法将不会触发;它看起来像是因为添加观察者时尚未设置Car to CarMileage关系(所以它实际上根本没有设置观察者)。我猜测有一种方法可以在方法中将-addObserver:forKeyPath:options:context调用移动到Car中,该方法将新的CarMileage对象添加到关系集中,所以我不会遇到这个问题。我不知道我是否应该搞乱Core Data自己的代码,这可能是高度优化的,而且,我不知道代码应该如何正常读取,所以我担心完全弄乱我的关系。我听说过有关“发电机”的一些信息,但是我找不到文档,当我已经困惑时,我觉得使用另一个我不太懂的程序感到有些不舒服......

有谁知道我应该从哪里打电话给-addObserver:forKeyPath:options:context,如果是关系设定的地方,我会怎么做?或者我将如何通过通知以原始方式执行此操作?

1 个答案:

答案 0 :(得分:0)

傻,傻,我。我的-updatePercentMileageForWork方法正在调用carMileage。@ sum.mileageForWork,它会发布一个重新计算的新通知,设置一个无限循环。所以我将CarMileage -mileageForWork方法更改为:

- (float) mileageForWork {
    float newMileageForWork;
    if ([self.forWork boolValue] == YES) {
        newMileageForWork = [self.mileage floatValue];
    } else {
        newMileageForWork = 0;
    }

    if (newMileageForWork == mileageForWork) {
        return mileageForWork;
    } else {
        mileageForWork = newMileageForWork;
        [[NSNotificationCenter defaultCenter] postNotificationName: @"mileageForWorkChanged" object:self];
        NSLog(@"send notification");
        return mileageForWork;
    }

}

这样它只会发送通知,如果它实际上是一个新值,而不是每次都发送。这留下了另一个问题,即当为该Car添加新的CarMileage对象(即新行程)时,mileageForWork和newMileageForWork都将默认为0,因此不会发送任何通知。我刚刚使用mileageForWork = 1覆盖-awakeFromInsert on CarMileage并且一切正常,但这意味着当插入新对象时通知循环运行两次。但在我看来,具有特定循环运行两次仍然比每次任何对象更改时发送通知更有效,就像使用NSManagedObjectContextObjectsDidChangeNotification一样。