我有这个accessDate字段,在数据模型中设置为日期类型。我在访问时使用object.accessDate = [NSDate date]
更新accessDate。
它是一个多线程应用程序,我已经完成了2个实现,一个具有共享的NSManagedObjectContext和适当的锁,另一个具有多个上下文和适当的合并,两者都偶尔抛出这个异常。
我在流程环境中设置了NSZombieEnabled。我有点想法,所以我很高兴听到一些新的建议。
编辑:我忘了添加它只发生在Mac OS X 10.6上
例外是:
(gdb) po $rax
-[__NSCFDate longLongValue]: unrecognized selector sent to instance 0x16ddf3020
该对象看起来并不可疑:
(gdb) po 0x16ddf3020
2012-07-18 18:11:35 +0200
(gdb) po [0x16ddf3020 class]
__NSCFDate
和回溯:
(gdb) bt
#0 0x00007fff8973deea in objc_exception_throw ()
#1 0x00007fff803bc110 in -[NSObject(NSObject) doesNotRecognizeSelector:] ()
#2 0x00007fff803348ef in ___forwarding___ ()
#3 0x00007fff80330a38 in __forwarding_prep_0___ ()
#4 0x00007fff831ad540 in -[NSSQLiteConnection execute] ()
#5 0x00007fff831f8e85 in -[NSSQLiteConnection updateRow:] ()
#6 0x00007fff831f801b in -[NSSQLConnection performAdapterOperation:] ()
#7 0x00007fff831f7f50 in -[NSSQLConnection performAdapterOperations:] ()
#8 0x00007fff831f7acb in -[NSSQLCore _performChangesWithAdapterOps:] ()
#9 0x00007fff831f680b in -[NSSQLCore performChanges] ()
#10 0x00007fff831f1259 in -[NSSQLCore saveChanges:] ()
#11 0x00007fff831b4c8b in -[NSSQLCore executeRequest:withContext:] ()
#12 0x00007fff831b4051 in -[NSPersistentStoreCoordinator(_NSInternalMethods) executeRequest:withContext:] ()
#13 0x00007fff831e8123 in -[NSManagedObjectContext save:] ()
答案 0 :(得分:0)
答案是“适当的锁定”毕竟不是真的。
我已将属性声明为
@property (nonatomic, retain) NSDate *accessDate;
并在实施文件中
@dynamic accessDate;
为了保证对属性的正确锁定我会想到
- (id)primitiveValueForKey:(NSString *)key
{
[[self managedObjectContext] lock];
id value = [super primitiveValueForKey:key];
[[self managedObjectContext] unlock];
return value;
}
就足够了,但实际上合成的Core Data属性根本不会调用primitiveValueForKey:
,这是对我的误解,所以事实上访问没有被正确锁定。答案可能是合成的Core Data访问器锁定10.7上下文,而不是10.6上。
所以我通过手动重新实现访问器解决了我的问题:
- (NSDate *)accessDate
{
[self willAccessValueForKey:@"accessDate"];
NSDate *date = [self primitiveValueForKey:@"accessDate"];
[self didAccessValueForKey:@"accessDate"];
return date;
}