更新NSManagedObject时EXC_BAD_ACCESS崩溃

时间:2013-01-18 14:27:57

标签: ios core-data nsmanagedobject nsmanagedobjectcontext nsoperation

我有一个从服务器提取JSON数据的应用程序,将数据解析为NSManagedObject子类,然后将这些NSManagedObject子类用作各种视图控制器中的属性。

我遇到的麻烦是,在将来的某个时刻,服务器上的数据会发生变化,这将触发更新请求。当尝试更新NSManagedObject子类时,如果用户然后尝试通过UI修改NSManagedObject,则应用程序崩溃。回答一个更新NSManagedObject关系的问题。

是否可以使用NSManagedObject向用户显示数据,同时在另一个线程上更新NSManagedObject的记录?

这是我在错误后得到的回溯:

* thread #1: tid = 0x1c03, 0x003d5e6d libsqlite3.dylib`sqlite3VdbeExec + 54749, stop reason = EXC_BAD_ACCESS (code=2, address=0x0)
frame #0: 0x003d5e6d libsqlite3.dylib`sqlite3VdbeExec + 54749
frame #1: 0x00343be1 libsqlite3.dylib`sqlite3_step + 3169
frame #2: 0x0071419f CoreData`_execute + 143
frame #3: 0x00714011 CoreData`-[NSSQLiteConnection execute] + 2801
frame #4: 0x007285ce CoreData`-[NSSQLChannel selectRowsWithStatement:] + 94
frame #5: 0x0073128f CoreData`newFetchedRowsForFetchPlan_MT + 1279
frame #6: 0x0071c6e3 CoreData`-[NSSQLCore newRowsForFetchPlan:] + 323
frame #7: 0x0071be07 CoreData`-[NSSQLCore objectsForFetchRequest:inContext:] + 711
frame #8: 0x0071b8f4 CoreData`-[NSSQLCore executeRequest:withContext:error:] + 404
frame #9: 0x0071aa6d CoreData`-[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 2445
frame #10: 0x007189c9 CoreData`-[NSManagedObjectContext executeFetchRequest:error:] + 569
frame #11: 0x0002f7a4 TQ`+[QTQCoreDataManager retrieveAllEntriesForEntityName:stringPredicate:orderBy:ascendingOrder:managedObjectContext:] + 532 at QTQCoreDataManager.m:103
frame #12: 0x0002fbcb TQ`+[QTQCoreDataManager retrieveFirstEntryForEntityName:stringPredicate:orderBy:ascendingOrder:managedObjectContext:] + 203 at QTQCoreDataManager.m:149
frame #13: 0x0002faa2 TQ`+[QTQCoreDataManager retrieveFirstEntryForEntityName:stringPredicate:orderBy:ascendingOrder:] + 226 at QTQCoreDataManager.m:129
frame #14: 0x000dd65e TQ`-[QTQTopic latestAnsweredSession] + 238 at QTQTopic.m:228
frame #15: 0x000dca29 TQ`-[QTQTopic isCompleted] + 185 at QTQTopic.m:157
frame #16: 0x000b5362 TQ`-[QTQTopicContainerViewController closeButtonPressed:] + 1442 at QTQTopicContainerViewController.m:376
frame #17: 0x01be2705 libobjc.A.dylib`-[NSObject performSelector:withObject:withObject:] + 77
frame #18: 0x00b19920 UIKit`-[UIApplication sendAction:to:from:forEvent:] + 96
frame #19: 0x00b198b8 UIKit`-[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
frame #20: 0x00bda671 UIKit`-[UIControl sendAction:to:forEvent:] + 66
frame #21: 0x00bdabcf UIKit`-[UIControl(Internal) _sendActionsForEvents:withEvent:] + 578
frame #22: 0x00bd9d38 UIKit`-[UIControl touchesEnded:withEvent:] + 546
frame #23: 0x00b4933f UIKit`-[UIWindow _sendTouchesForEvent:] + 846
frame #24: 0x00b49552 UIKit`-[UIWindow sendEvent:] + 273
frame #25: 0x00b273aa UIKit`-[UIApplication sendEvent:] + 436
frame #26: 0x00b18cf8 UIKit`_UIApplicationHandleEvent + 9874
frame #27: 0x02e47df9 GraphicsServices`_PurpleEventCallback + 339
frame #28: 0x02e47ad0 GraphicsServices`PurpleEventCallback + 46
frame #29: 0x02166bf5 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
frame #30: 0x02166962 CoreFoundation`__CFRunLoopDoSource1 + 146
frame #31: 0x02197bb6 CoreFoundation`__CFRunLoopRun + 2118
frame #32: 0x02196f44 CoreFoundation`CFRunLoopRunSpecific + 276
frame #33: 0x02196e1b CoreFoundation`CFRunLoopRunInMode + 123
frame #34: 0x02e467e3 GraphicsServices`GSEventRunModal + 88
frame #35: 0x02e46668 GraphicsServices`GSEventRun + 104
frame #36: 0x00b1665c UIKit`UIApplicationMain + 1211
frame #37: 0x00005fcd TQ`main + 141 at main.m:16

1 个答案:

答案 0 :(得分:0)

有点......不是相同的MO,而是相同的实体。

问题是MO不是线程安全的,但是objectID是

所以...

  1. 获取UI主线程中的MO

  2. 获取其ObjectID并在bg线程中使用它 (在这里再次获取)

  3. 在主线程完成后更新对象(call [context refreshObject:object])