【问题标题】:Core Data: setPrimitiveValue:forKey: behaves really weirdly核心数据:setPrimitiveValue:forKey: 行为真的很奇怪
【发布时间】:2014-01-07 05:28:03
【问题描述】:

这是个谜:

我在NSManagedObject 上调用setPrimitiveValue:forKey:。关键是对象的合法、持久、建模属性。但是,setPrimitiveValue:forKey: 失败,通常为 不同 任意属性设置值。文档说,在为未建模的密钥调用 setPrimitiveValue:forKey: 时会出现这种行为。因此,Core Data 似乎认为密钥未建模。

奇怪的部分:

当键被硬编码为字符串文字时,原始值确实设置成功。只有当键是变量时才会失败。我正在使用的变量恰好是从observeValueForKeyPath:ofObject:change:context:keyPath 参数传递的

keyPath 变量与字符串文字相同。 isEqual: 返回 true 并且哈希值相等。 keyPath 变量的类型为 __NSCFString。有谁知道为什么setPrimitiveValue:forKey: 的行为会有所不同? (此行为在 OS X 10.9.1 上)


提供更好信息的更新:

行为不端的键追溯到从磁盘上的文件加载的字符串。下面的例子是一个孤立的案例。如果属性字符串“mainAttr”被写入磁盘并读回,则setPrimitiveValue:forKey: 设置了错误属性的值,而不是“mainAttr”。

核心数据对象:

@interface Boo : NSManagedObject
@property (nonatomic, retain) NSNumber * mainAttr;
@property (nonatomic, retain) NSNumber * attr1;
@property (nonatomic, retain) NSNumber * attr2;
@property (nonatomic, retain) NSNumber * attr3;
@end

-

#import "Boo.h"

int main(int argc, const char * argv[]) {
    @autoreleasepool {
            NSManagedObjectContext *context = managedObjectContext();
    NSString *key = @"mainAttr";

    // write to disk, read back in
    NSString *path = [@"~/Desktop/test.txt" stringByExpandingTildeInPath];
    [key writeToFile:path atomically:YES encoding:NSUTF8StringEncoding error:NULL];
    key = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:NULL];

    Boo *boo = [NSEntityDescription insertNewObjectForEntityForName:@"Boo" inManagedObjectContext:context];
    [boo setPrimitiveValue:@(5) forKey:key];

    NSLog(@"Boo: %@", boo);
    }
    return 0;
}

【问题讨论】:

  • 我们在 iOS 上也看到了类似的行为,保存时失败并出现“通用”验证错误。您的问题对为什么会发生这种情况提出了一个有趣的看法。
  • 我不知道,但我有兴趣查看observeValueForKeyPath:ofObject:change:context: 中出现问题的代码。
  • 你能把它放到一个测试项目中吗?
  • 我正在尝试将它隔离在一个测试项目中,但当然行为并没有在那里表现出来......但是
  • 用示例更新了原始帖子

标签: ios core-data key-value-observing kvc object-equality


【解决方案1】:

您需要以下 3 个语句来设置值。试试看。

[self willChangeValueForKey:key];
[boo setPrimitiveValue:@(5) forKey:key];
[self didChangeValueForKey:key];

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-08-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多