0

我有这个 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:] ()
4

1 回答 1

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;
}
于 2012-07-20T08:36:32.450 回答