数组索引越界问题(NSRangeException)在-[NSManagedObjectContext save:]中发生。
数组索引越界问题(NSRangeException)在-[NSManagedObjectContext save:]中发生。
我的iOS应用刚刚在-[NSManagedObjectContext save:]
中遇到了NSRangeException
的崩溃。任何其他有帮助的信息都找不到。我该如何修复这个问题?我没有得到任何内存地址或其他可以使用的信息...
2015-04-22 14:16:38.078 heavenhelp[33559:1734247] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 6 beyond bounds [0 .. 5]' *** First throw call stack: ( 0 CoreFoundation 0x0167f746 __exceptionPreprocess + 182 1 libobjc.A.dylib 0x00f40a97 objc_exception_throw + 44 2 CoreFoundation 0x01553b73 -[__NSArrayM objectAtIndex:] + 243 3 CoreData 0x00859cf3 -[NSSQLCore recordToManyChangesForObject:inRow:usingTimestamp:inserted:] + 2531 4 CoreData 0x00856a0b -[NSSQLCore _populateRow:fromObject:timestamp:inserted:] + 2923 5 CoreData 0x00776e24 -[NSSQLCore prepareForSave:] + 1764 6 CoreData 0x00775e3d -[NSSQLCore saveChanges:] + 461 7 CoreData 0x0073f15e -[NSSQLCore executeRequest:withContext:error:] + 638 8 CoreData 0x0083ee75 __65-[NSPersistentStoreCoordinator executeRequest:withContext:error:]_block_invoke + 5349 9 CoreData 0x008492ff gutsOfBlockToNSPersistentStoreCoordinatorPerform + 191 10 libdispatch.dylib 0x035f4bef _dispatch_client_callout + 14 11 libdispatch.dylib 0x035d7b0d _dispatch_barrier_sync_f_invoke + 144 12 libdispatch.dylib 0x035d723f dispatch_barrier_sync_f + 105 13 CoreData 0x008383f7 _perform + 183 14 CoreData 0x0073ec8b -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 459 15 CoreData 0x0076ee09 -[NSManagedObjectContext save:] + 1529 16 heavenhelp 0x000b6834 _TF10heavenhelp11saveContextFT_T_ + 324 17 heavenhelp 0x0015368d _TFC10heavenhelp26ConversationViewController17viewWillDisappearfS0_FSbT_ + 701 18 heavenhelp 0x001536ef _TToFC10heavenhelp26ConversationViewController17viewWillDisappearfS0_FSbT_ + 63 19 UIKit 0x020a4292 -[UIViewController _setViewAppearState:isAnimating:] + 706 20 UIKit 0x020a4904 -[UIViewController __viewWillDisappear:] + 106 21 UIKit 0x020bcd1d -[UIViewController(UIContainerViewControllerProtectedMethods) beginAppearanceTransition:animated:] + 200 22 UIKit 0x020cafec -[UINavigationController _startCustomTransition:] + 1028 23 UIKit 0x020d8e00 -[UINavigationController _startDeferredTransitionIfNeeded:] + 712 24 UIKit 0x020d9a51 -[UINavigationController __viewWillLayoutSubviews] + 57 25 UIKit 0x02253750 -[UILayoutContainerView layoutSubviews] + 213 26 UIKit 0x01fce57a -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 668 27 libobjc.A.dylib 0x00f56771 -[NSObject performSelector:withObject:] + 70 28 QuartzCore 0x01d5ee47 -[CALayer layoutSublayers] + 144 29 QuartzCore 0x01d52925 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 403 30 QuartzCore 0x01d5277a _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26 31 QuartzCore 0x01caec52 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 284 32 QuartzCore 0x01cb00e5 _ZN2CA11Transaction6commitEv + 487 33 QuartzCore 0x01cb07fc _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92 34 CoreFoundation 0x015a086e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30 35 CoreFoundation 0x015a07b0 __CFRunLoopDoObservers + 400 36 CoreFoundation 0x015961ea __CFRunLoopRun + 1226 37 CoreFoundation 0x01595a5b CFRunLoopRunSpecific + 443 38 CoreFoundation 0x0159588b CFRunLoopRunInMode + 123 39 GraphicsServices 0x046cc2c9 GSEventRunModal + 192 40 GraphicsServices 0x046cc106 GSEventRun + 104 41 UIKit 0x01f3b106 UIApplicationMain + 1526 42 heavenhelp 0x000a5c94 main + 180 43 libdyld.dylib 0x0361fac9 start + 1 ) libc++abi.dylib: terminating with uncaught exception of type NSException
这是我用来使我的save:
线程安全的代码:
static var onceToken: dispatch_once_t = 0
static var singleton: CoreDataHelper!
static var sharedInstance: CoreDataHelper {
get {
dispatch_once(&onceToken, {
self.singleton = CoreDataHelper()
})
return singleton
}
}
我的xcdatamodeld
(相关部分):
编辑:我已经编辑了代码,以反映我对使我的NSManagedObjectContext
线程安全所做的更改。现在,我在一个我上面初始化的CoreDataHelper
实例上进行所有操作。我发现,通过进入一个对话,添加一条消息,然后进入另一个对话并在那里添加一条消息,我可以触发崩溃。我已经添加了我的xcdatamodeld
。
Array Index Out of Bounds issue (NSRangeException) in -[NSManagedObjectContext save:]
在AppDelegate中的某个地方,你创建了一个NSArray。
通过添加异常断点,你可以检查引发错误的行。
添加异常断点的方法可以在以下链接中找到。
http://blog.manbolo.com/2012/01/23/xcode-tips-1-break-on-exceptions
https://developer.apple.com/library/ios/recipes/xcode_help-breakpoint_navigator/articles/adding_an_exception_breakpoint.html
我不能接受这个答案,但我可以告诉你我在AppDelegate中没有创建NSArray。我为你添加异常断点的建议投了赞成票。
添加异常断点后显示错误发生在[NSManagedObjectContext save:]中...我现在该怎么办?
好吧,错误发生在我插入一个新对象之后,但它并不总是发生,这很奇怪。错误只是在默认的managedObjectContext的.save(&error)方法上发生(UIApplication.sharedApplication().delegate as! AppDelegate).managedObjectContext。我不知道我应该分享什么。我在completionHandler的dataTaskWithRequest:方法中创建了NSManagedObject(通过dispatch_async(dispatch_get_main_queue())发送到主队列),但错误直到我在这个completionHandler之外创建对象时才发生。
在模拟器中运行应用程序会得到更好的错误信息;我编辑了我的问题。
当在recordToManyChangesForObject:inRow:usingTimestamp:inserted:方法上设置断点时(该方法访问错误的索引),我感觉我的completionhandlers中进行了保存,而在其他completionhandlers中也进行了保存。有没有办法确保方法在执行时不重叠?
在上述对话中,我们可以看到讨论了一个关于"Array Index Out of Bounds issue (NSRangeException) in -[NSManagedObjectContext save:]"问题的原因和解决方法。
根据代码和对话内容,我们可以得出以下结论:
问题的原因:
- 问题出现在使用多线程的情况下,当在不同线程上使用已创建的NSManagedObjectContext时,会发生数组越界错误。
解决方法:
- 使用NSPrivateQueueConcurrencyType初始化NSManagedObjectContext对象,以确保在多线程环境下的安全性。
- 使用performBlock或performBlockAndWait方法来同步访问NSManagedObjectContext对象,确保在正确的线程上执行操作。
以下是整理后的
在使用Core Data时,有一个常见的问题是"Array Index Out of Bounds issue (NSRangeException) in -[NSManagedObjectContext save:]"。这个问题通常出现在多线程环境下,特别是在不同线程上使用已创建的NSManagedObjectContext时。下面是一个关于这个的问题和解决方法。
讨论中给出了一段代码,展示了如何创建一个线程安全的保存方法。该方法使用了一个全局NSLock对象来锁定和解锁save方法。然而,如果在不同于创建它的线程上使用NSManagedObjectContext,那么这个锁是无用的。因此,为了解决这个问题,讨论中提到了performBlock和performBlockAndWait方法,这些方法可以用来同步访问NSManagedObjectContext对象。
解决方法的关键在于使用NSPrivateQueueConcurrencyType来初始化NSManagedObjectContext对象。这样可以确保在多线程环境下的安全性。然后,使用performBlock或performBlockAndWait方法来同步访问NSManagedObjectContext对象,以确保在正确的线程上执行操作。
如果仍然遇到问题,可以尝试创建一个最小化的应用程序来复现这个问题,并进一步排查错误。这样可以更好地定位问题所在,并有助于进一步调试和修复。
,解决"Array Index Out of Bounds issue (NSRangeException) in -[NSManagedObjectContext save:]"问题的关键在于正确处理多线程环境下的NSManagedObjectContext对象。通过使用正确的并发类型初始化NSManagedObjectContext对象,并使用performBlock或performBlockAndWait方法来同步访问,可以避免这个问题的发生。