これは謎です:
で呼び出しsetPrimitiveValue:forKey:
ていNSManagedObject
ます。キーは、オブジェクトの正当で永続的なモデル化された属性です。ただし、 setPrimitiveValue:forKey: は失敗し、別の任意の属性の値を設定することがよくあります。setPrimitiveValue:forKey:
ドキュメントによると、モデル化されていないキーを呼び出すときに、この動作が予期されるとのことです。そのため、Core Data はキーがモデル化されていないと考えているようです。
奇妙な部分:
キーが文字列リテラルとしてハードコーディングされている場合、プリミティブ値は実際に正常に設定されます。キーが変数の場合にのみ失敗します。私が使用している変数は、たまたまのkeyPath
引数から渡されますobserveValueForKeyPath:ofObject:change:context:
変数は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;
}