0

我敢肯定有人以前看过这个,我可能遗漏了一些明显的东西......这是简要说明:我有一个核心数据应用程序,它有 Car 和 CarMileage,更准确地认为是汽车旅行(汽车 < -->>汽车里程)。CarMileage 包含一些属性,包括里程(浮动、行程长度)和 forWork (BOOL)。我制作了一个包含 mileageForWork 的自定义 CarMileage 类(浮点数,如果 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 部分。日志显示“send notification”、percentMileageForWork 的值和“awakeFromFetch”,然后程序暂停,XCode 中的线程选项卡弹出 szone_malloc_should_clear, EXC_BAD_ACCESS code = 2。

我完全不知道为什么会这样。在我经验不足的情况下,问题在于应该在哪里观察通知。毕竟,帖子会产生日志。任何想法为什么它会崩溃?

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

有谁知道我应该-addObserver:forKeyPath:options:context从哪里打电话,如果是从哪里建立关系,我会怎么做?或者我将如何按照我原本打算的方式通过通知来做到这一点?

4

1 回答 1

0

傻,傻我。我的 -updatePercentMileageForWork 方法正在调用 carMileage.@sum.mileageForWork,它会发布一个它已重新计算的新通知,从而设置一个无限循环。所以我将 CarMilage -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;
    }

}

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

于 2012-10-20T15:59:04.900 回答