7

これは謎です:

で呼び出し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;
}
4

1 に答える 1