更新NSManagedObject时,EXC_BAD_ACCESS崩溃 [英] EXC_BAD_ACCESS crash when updating NSManagedObject

查看:136
本文介绍了更新NSManagedObject时,EXC_BAD_ACCESS崩溃的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



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



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



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

 code> * 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
帧#9:0x0071aa6d CoreData`- [NSPersistentStoreCoordinator executeRequest:withContext:error:] + 2445
帧#10:0x007189c9 CoreData`- [NSManagedObjectContext executeFetchRequest:error:] + 569
帧#11:0x0002f7a4 TQ `+ [QTQCoreDataManager retrieveAllEntriesForEntityName:stringPredicate:orderBy:ascendingOrder:managedObjectContext:] + QTQCoreDataManager.m中的+ 532:
frame#12:0x0002fbcb TQ` + [QTQCoreDataManager retrieveFirstEntryForEntityName:stringPredicate:orderBy:ascendingOrder:managedObjectContext:] + 203在QTQCoreDataManager.m:149
帧#13:0x0002faa2 TQ` + QTQCoreDataManager retrieveFirstEntryForEntityName:stringPredicate:排序依据:ascendingOrder:] + 226处QTQCoreDataManager.m:129
帧#14:0x000dd65e TQ`- [ QTQTopic latestAnsweredSession] + 238处QTQTopic.m:228
帧#15:0x000dca29 TQ`- [QTQTopic isCompleted] + 185处QTQTopic.m:157
帧#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:到:forEvent:] + 66
帧#21:0x00bdabcf UIKit`- [UIControl(内部)_sendActionsForEvents:withEvent:方法] + 578
帧#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
帧#26:0x00b18cf8 UIKit`_UIApplicationHandleEvent + 9874
帧#27:0x02e47df9 GraphicsServices`_PurpleEventCallback + 339
帧#28:0x02e47ad0 GraphicsServices `PurpleEventCallback + 46
帧#29:0x02166bf5 CoreFoundation`__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
帧#30:0x02166962 CoreFoundation`__CFRunLoopDoSource1 + 146
帧#31:0x02197bb6 CoreFoundation`__CFRunLoopRun + 2118
帧#32:0x02196f44 CoreFoundation`CFRunLoopRunSpecific + 276
帧#33:0x02196e1b CoreFoundation`CFRunLoopRunInMode + 123
帧#34:0x02e467e3 GraphicsServices`GSEventRunModal + 88
帧#35:0x02e46668 GraphicsServices`GSEventRun + 104
frame#36:0x00b1665c UIKit`UIApplicationMain + 1211
frame#37:0x00005fcd TQ`main + 141 at main.m:16


解决方案

kinda ..不是同一个MO,但是同一个实体。



这是因为MO不是线程安全的,而是objectID是



所以...


  1. 获取UI的主线程中的MO


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


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



I have an application that pulls JSON data from a server, parses the data into NSManagedObject subclasses and these NSManagedObject subclasses are then used as properties in various view controllers.

The trouble I'm having is that at some point in the future the data on the server will change and this will trigger an update pull request. When attempting to update the NSManagedObject subclasses, the app is crashing if the user then attempts to modify NSManagedObject via the UI by e.g. answering a question which updates a relationship on that NSManagedObject.

Is it possible to use NSManagedObject to both display data to the user and at the same time update that NSManagedObject's record on a different thread?

This is the backtrace that I'm getting after the error:

* 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

解决方案

kinda.. not the same MO but the same entity.

the thing is that MOs aren't threadsafe but objectIDs are

so...

  1. get the MO in main thread for UI

  2. get its ObjectID and use it in bg thread (fetch it again here)

  3. update the object after you are done in main thread (call [context refreshObject:object])

这篇关于更新NSManagedObject时,EXC_BAD_ACCESS崩溃的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆