在存储到 Core Data 之前拦截 Restkit 映射

Intercepting Restkit mapping before it is stored in Core Data

在将对象存储到 Core Data 之前更新来自服务器的对象的正确方法是什么?我有一个 class 和 "local" 属性,我必须在存储它之前对其进行更新。

我的模型中有一个 class

@interface classA : NSManagedObject {}

@property (nonatomic, strong) NSNumber* customAttribute;

@end

customAttribute不在JSON中,必须在对象存储到CD之前为其分配一个特殊值。我在 UITableView 中显示 JSON 内容,但在通知 NSFetchedResultsController 之前,我需要初始化值 customAttribute

更新:一种可能的解决方案是使用Key Value Validation:

我是这样使用验证方法的:

- (BOOL)validateEntityId:(inout __autoreleasing id *)ioValue error:(out NSError *__autoreleasing *)outError {

    self.customAttribute = [[AppConfiguration sharedInstance].sortIndexes objectForKey:*ioValue];

    if(self.customAttribute == nil) {

        self.customAttribute = @(9999);
    }

    return YES;
}

但是当我 运行 应用程序时,我得到了这个异常:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Failed to process pending changes before save. The context is still dirty after 1000 attempts. Typically this recursive dirtying is caused by a bad validation method, -willSave, or notification handler.

我还从映射中排除了 customAttribute 属性。但我仍然得到例外。 (映射exclusion/inclusion与解决方案无关。

更新 2:

验证方法应该只为 *ioValue 赋值。它不应更改 class 或 superclass 的任何其他值,但它可以从不同的已初始化 class 属性.

分配一个值

KVC 验证方法应该有效,您只需要通过在您不(或不应该)进行更改时触发更改通知来确保您不会总是弄脏对象。

目前您的代码:

self.customAttribute = [[AppConfiguration sharedInstance].sortIndexes objectForKey:*ioValue];

if(self.customAttribute == nil) {

    self.customAttribute = @(9999);
}

始终设置 self.customAttribute,这会触发更改通知,然后读回它,这会触发更多通知,然后可能会再次设置它,但还会有更多通知。

将其更改为使用原始访问器来检查是否需要进行更改。如果新值等于当前值,或者您要将其设置为 nil 然后再设置为其他值,请先解决这个问题。然后,一旦您知道要进行哪些更改 - 如果有的话 - 进行更改。

大多数情况下,关键是如果你能帮助它,不要做出改变,因为重复的改变是你得到一个对象仍然脏的循环的原因......