【发布时间】:2013-12-06 22:07:21
【问题描述】:
我在一个简单的 Core Data 项目中遇到了崩溃。
我使用 Core Data 创建了一个新的空 iPhone 项目。两个实体以一对一的反向关系添加到数据模型中。两者都有自动生成的 NSManagedObject 子类。实体名称和类都设置在两者上。
DBMove
attribute: moveValue:Integer16
relationship: newPosition -> DBPosition (inverse: move)
DBPosition
attribute: positionValue:Integer16
relationship: move -> DBMove (inverse: newPosition)
有一个创建 DBMove 和 DBPosition 的自定义视图控制器。然后它设置它们之间的反比关系并保存它。从应用程序委托中检索托管对象上下文;我认为这是安全的,因为 [NSThread isMultiThreaded] 返回 false。
- (void)newEntries
{
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = appDelegate.managedObjectContext;
DBPosition *newPos = [NSEntityDescription
insertNewObjectForEntityForName:@"DBPosition"
inManagedObjectContext:context];
newPos.positionValue = [NSNumber numberWithInt:5];
DBMove *newMove = [NSEntityDescription
insertNewObjectForEntityForName:@"DBMove"
inManagedObjectContext:context];
newMove.moveValue = [NSNumber numberWithInt:2];
newPos.move = newMove;
NSError *error;
if (![context save:&error]) {
NSLog(@"Save error: %@", [error localizedDescription]);
}
}
然后视图控制器获取所有 DBMove。它们的 Integer16 属性按预期输出。 [编辑] 访问关系会导致 main::@autoreleasepool 中的 EXC_BAD_ACCESS 在循环遍历 所有 获取结果后的某个时间发生。在崩溃之前,之前程序中数据库中的所有 DBMove 和 DBPosition 条目都可以正确打印,然后是我的 ViewController init 中的 NSLogs;崩溃似乎延迟了。大约每 5 次程序运行中出现 4 次。 [结束编辑]
- (void)printMoves
{
AppDelegate *appDelegate = (AppDelegate*)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext *context = appDelegate.managedObjectContext;
NSError *error;
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"DBMove"
inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
for (DBMove *move in fetchedObjects) {
DBPosition *newPos = move.newPosition; // <--- all's well without this reference!
NSLog(@"Move : %d", [move.moveValue intValue]);
NSLog(@"Position : %d", [newPos.positionValue intValue]);
}
}
NSZombieEnabled=YES 使程序正常运行并打印预期值。在整个执行过程中,我的上下文似乎是相同的。
这是堆栈跟踪:
#0 0x018300b2 in objc_msgSend ()
#1 0x00256ffc in -[_CDSnapshot dealloc] ()
#2 0x0025573d in -[_CDSnapshot release] ()
#3 0x00260384 in -[NSManagedObject(_NSInternalMethods) _clearRawPropertiesWithHint:] ()
#4 0x0026018b in -[NSFaultHandler turnObject:intoFaultWithContext:] ()
#5 0x002607ba in -[NSManagedObject dealloc] ()
#6 0x00257b88 in -[_PFManagedObjectReferenceQueue _processReferenceQueue:] ()
#7 0x00232fe1 in _performRunLoopAction ()
#8 0x01a654ce in __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ ()
#9 0x01a6541f in __CFRunLoopDoObservers ()
#10 0x01a43344 in __CFRunLoopRun ()
#11 0x01a42ac3 in CFRunLoopRunSpecific ()
#12 0x01a428db in CFRunLoopRunInMode ()
#13 0x038fe9e2 in GSEventRunModal ()
#14 0x038fe809 in GSEventRun ()
#15 0x0058ed3b in UIApplicationMain ()
#16 0x0000396d in main at /Users/brian/devel/test2-CoreData/test2-CoreData/main.m:16
当我在空的新项目上检查“核心数据”时,所有核心数据设置都来自标准包含。
大概我过度释放了一个托管对象,但是在哪里?
【问题讨论】:
-
你的代码看起来不错...这可能是别的东西。您是否尝试将应用程序从模拟器上擦除并重新安装?
-
不是检查多线程,而是检查线程是主线程。如下, if ([NSThread currentThread] == [NSThread mainThread]){ }
-
关系通常是
NSSet- 因此将DBMove对象分配给一组可能是问题所在(尽管我预计会出现与您在上面显示的错误消息不同的错误消息)。跨度> -
@Mundi,我每隔几次运行就删除模拟器上的应用程序,选择 Product->Clean,然后重建。我同意你的评价。
-
@Arun,感谢主线程代码。它在这两种方法以及创建上下文、持久存储协调器和托管对象模型的应用程序委托方法中报告主线程。
标签: ios objective-c core-data nsmanagedobject