简体   繁体   English

核心数据:setPrimitiveValue:forKey:表现得非常奇怪

[英]Core Data: setPrimitiveValue:forKey: behaves really weirdly

This is a mystery: 这是一个谜:

I'm invoking setPrimitiveValue:forKey: on an NSManagedObject . 我在NSManagedObject上调用setPrimitiveValue:forKey: . The key is a legit, persistent, modeled attribute of the object. 关键是对象的合法,持久,建模属性。 However, setPrimitiveValue:forKey: fails, often setting the value for a different , arbitrary attribute. 但是,setPrimitiveValue:forKey:失败,通常为不同的任意属性设置值。 The docs say this behavior is expected when invoking setPrimitiveValue:forKey: for an unmodeled key. 文档说当调用setPrimitiveValue:forKey:对于未建模的密钥时,会出现这种行为。 So it seems Core Data thinks the key is unmodeled. 所以似乎Core Data认为密钥是未建模的。

The strange part: 奇怪的部分:

When the key is hardcoded as a string literal, the primitive value is indeed set successfully. 当密钥被硬编码为字符串文字时,原始值确实成功设置。 It only fails when the key is a variable. 它只在键是变量时失败。 The variable I'm using happens to be passed from the keyPath argument of observeValueForKeyPath:ofObject:change:context: 我正在使用的变量恰好从keyPath参数observeValueForKeyPath:ofObject:change:context:

The keyPath variable is the same as the string literal. keyPath变量与字符串文字相同。 isEqual: returns true and the hash values are equal. isEqual:返回true,哈希值相等。 The keyPath variable is of type __NSCFString . keyPath变量的类型为__NSCFString Does anyone know why setPrimitiveValue:forKey: would behave any differently? 有谁知道为什么setPrimitiveValue:forKey:会有什么不同的行为? (This behavior is on OS X 10.9.1) (此行为在OS X 10.9.1上)


An update with better information: 更新信息更新:

The misbehaving key traced back to a string loaded from a file on disk. 行为不当的密钥追溯到从磁盘上的文件加载的字符串。 The example below is an isolated case. 以下示例是一个孤立的案例。 If the attribute string "mainAttr" is written to disk and read back in, then setPrimitiveValue:forKey: sets the value for the wrong attribute, not "mainAttr". 如果将属性字符串“mainAttr”写入磁盘并读回,则setPrimitiveValue:forKey:设置错误属性的值,而不是“mainAttr”。

Core data object: 核心数据对象:

@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;
}

You need the below 3 statements to set the value. 您需要以下3个语句来设置值。 Try it. 试试吧。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM