Array Index Out of Bounds issue (NSRangeException) in -[NSManagedObjectContext save:] - ios

My iOS application just crashed with a NSRangeException on -[NSManagedObjectContext save:]. Nothing else helpful anywhere to be found. How am I supposed to fix this? I don't get any memory address or anything that I can work with...
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
This is the code I used to make my save: thread-safe:
static var onceToken: dispatch_once_t = 0
static var singleton: CoreDataHelper!
static var sharedInstance: CoreDataHelper {
get {
dispatch_once(&onceToken, {
self.singleton = CoreDataHelper()
})
return singleton
}
}
My xcdatamodeld (the relevant part):
Edits: I have edited the code to reflect my changes to make my NSManagedObjectContext thread-safe. Everything I do now, I do on one instance of my CoreDataHelper that I initialise as above. I have found I can trigger a crash by going into one conversation, adding a message, going into another conversation and adding a message there. I have added my xcdatamodeld.

I had apparently set my one-to-many relationship between conversations and messages to "ordered". This was not correct... I had already changed my NSManagedObject's class to use NSMutableSet instead of NSMutableOrderedSet.
Apparently this results in an NSRangeException in the save method...

you said you have made your save-method thread save. can you please show some code?
usually i'm doing something like this:
// create object with concurrency where you need it
[[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
// wrapper for saving
- (BOOL)saveContext
{
__block BOOL success = NO;
NSManagedObjectContext *managedObjectContext = self.managedObjectContext;
if (managedObjectContext != nil)
{
[managedObjectContext performBlockAndWait:^{
if([managedObjectContext hasChanges])
{
NSError *error = nil;
success = [managedObjectContext save:&error];
if (success == NO)
{
NSLog(#"Unresolved error %#", error.localizedDescription);
}
}
}];
}
return success;
}

Somewhere in AppDelegate you are creating NSArray,
By adding Exception Breakpoint you can check the line which causes error.
method to add Exception Breakpoint is on the following links.
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

Related

CoreData Error SIGABRT: keypath AttributeName not found in entity <NSSQLEntity EntityName id=2>

I use core data in my iOS App. I have two entities, "Commit", with attributes "commitID", "completionStatus", "contents" and "repeatStatus" as well as an entity "ToDoList" with the attribute "dateID". The two are connected via a relationship that relates many Commits to one ToDoList.
I get the following error every time. I have tried deleting and reinstalling the app, to no avail. I know this error is thrown after my application(application: didFinishLaunchingWithOptions:) method:
2016-05-07 10:54:14.131 CommitToday[1836:47383] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'keypath commitID not found in entity <NSSQLEntity ToDoList id=2>'
*** First throw call stack:
(
0 CoreFoundation 0x00000001027d7d85 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010457bdeb objc_exception_throw + 48
2 CoreData 0x000000010242efff -[NSSQLGenerator newSQLStatementForRequest:ignoreInheritance:countOnly:nestingLevel:nestIsWhereScoped:] + 1583
3 CoreData 0x00000001023217e3 -[NSSQLGenerator newSQLStatementForFetchRequest:ignoreInheritance:countOnly:nestingLevel:nestIsWhereScoped:] + 35
4 CoreData 0x00000001024147b8 -[NSSQLAdapter _statementForFetchRequest:ignoreInheritance:countOnly:nestingLevel:] + 344
5 CoreData 0x000000010232167c -[NSSQLAdapter _newSelectStatementWithFetchRequest:ignoreInheritance:] + 316
6 CoreData 0x00000001023212f6 -[NSSQLCore newRowsForFetchPlan:] + 118
7 CoreData 0x0000000102320bac -[NSSQLCore objectsForFetchRequest:inContext:] + 524
8 CoreData 0x0000000102320549 -[NSSQLCore executeRequest:withContext:error:] + 377
9 CoreData 0x0000000102405eaf __65-[NSPersistentStoreCoordinator executeRequest:withContext:error:]_block_invoke + 3311
10 CoreData 0x000000010240f4dd gutsOfBlockToNSPersistentStoreCoordinatorPerform + 189
11 CoreData 0x00000001024005ed _perform + 221
12 CoreData 0x00000001023201b4 -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 500
13 CoreData 0x000000010231e973 -[NSManagedObjectContext executeFetchRequest:error:] + 579
14 CoreData 0x000000010244d6c2 __43-[NSFetchedResultsController performFetch:]_block_invoke + 258
15 CoreData 0x000000010240f4dd gutsOfBlockToNSPersistentStoreCoordinatorPerform + 189
16 libdispatch.dylib 0x00000001050143eb _dispatch_client_callout + 8
17 libdispatch.dylib 0x0000000104ff8ef5 _dispatch_barrier_sync_f_invoke + 393
18 CoreData 0x00000001023ff076 -[NSPersistentStoreCoordinator performBlockAndWait:] + 198
19 CoreData 0x0000000102366127 developerSubmittedBlockToNSManagedObjectContextPerform + 199
20 CoreData 0x0000000102365fee -[NSManagedObjectContext performBlockAndWait:] + 222
21 CoreData 0x000000010244d4bc -[NSFetchedResultsController performFetch:] + 524
22 CommitToday 0x00000001022404e4 _TFC11CommitToday14ViewController11viewDidLoadfT_T_ + 164
23 CommitToday 0x0000000102240d42 _TToFC11CommitToday14ViewController11viewDidLoadfT_T_ + 34
24 UIKit 0x000000010319a984 -[UIViewController loadViewIfRequired] + 1198
25 UIKit 0x00000001031defae -[UINavigationController _layoutViewController:] + 54
26 UIKit 0x00000001031df882 -[UINavigationController _updateScrollViewFromViewController:toViewController:] + 462
27 UIKit 0x00000001031df9f4 -[UINavigationController _startTransition:fromViewController:toViewController:] + 126
28 UIKit 0x00000001031e0c4d -[UINavigationController _startDeferredTransitionIfNeeded:] + 890
29 UIKit 0x00000001031e1d0b -[UINavigationController __viewWillLayoutSubviews] + 57
30 UIKit 0x0000000103390503 -[UILayoutContainerView layoutSubviews] + 248
31 UIKit 0x00000001030ba980 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 703
32 QuartzCore 0x0000000107aafc00 -[CALayer layoutSublayers] + 146
33 QuartzCore 0x0000000107aa408e _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 366
34 QuartzCore 0x0000000107aa3f0c _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
35 QuartzCore 0x0000000107a983c9 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 277
36 QuartzCore 0x0000000107ac6086 _ZN2CA11Transaction6commitEv + 486
37 QuartzCore 0x0000000107ac67f8 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92
38 CoreFoundation 0x00000001026fcc37 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
39 CoreFoundation 0x00000001026fcba7 __CFRunLoopDoObservers + 391
40 CoreFoundation 0x00000001026f211c CFRunLoopRunSpecific + 524
41 UIKit 0x0000000102ffaf21 -[UIApplication _run] + 402
42 UIKit 0x0000000102ffff09 UIApplicationMain + 171
43 CommitToday 0x000000010223c302 main + 114
44 libdyld.dylib 0x000000010504892d start + 1
45 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
From the error message:
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'keypath commitID not found in entity [NSSQLEntity ToDoList id=2]'
it seems to be trying to access an attribute named commitID on the ToDoList entity. That suggests you have a fetch or fetched results controller that is configured incorrectly.

[__NSCFArray objectForKey:]: unrecognized selector sent to instance when fetching from Core Data

I am getting the error [__NSCFArray objectForKey:]: unrecognized selector sent to instance when trying to fetch some data from my Core Data.
I am relatively new to iOS programming and don't quite understand what this error is trying to tell me. I set an exception breakpoint to figure out which line is giving me the problem and it is this line of code:
if let fetchResults = managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as? [User] {
Why am I getting this error and how do I resolve it? Is this related to the way I save my Core Data? I just recently did a change where I receive a JSON from the server, then process in the background and then finally save changes to my ManagedObjectContext in the main thread.
func getUser(userId: String) -> User? {
let fetchRequest = NSFetchRequest(entityName: "User")
fetchRequest.predicate = NSPredicate(format: "userId == %#", userId)
fetchRequest.fetchLimit = 1
if let fetchResults = managedObjectContext!.executeFetchRequest(fetchRequest, error: nil) as? [User] {
if !fetchResults.isEmpty {
return fetchResults[0]
}
else {
println("UserId \(userId) not in database")
}
}
return nil
}
Error
2014-12-06 13:09:36.087 LFDate[3162:51570] -[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0x7fb9e95c4310
2014-12-06 13:09:36.090 LFDate[3162:51570] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFArray objectForKey:]: unrecognized selector sent to instance 0x7fb9e95c4310'
*** First throw call stack:
(
0 CoreFoundation 0x00000001025c2f35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010465ebb7 objc_exception_throw + 45
2 CoreFoundation 0x00000001025ca04d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x000000010252227c ___forwarding___ + 988
4 CoreFoundation 0x0000000102521e18 _CF_forwarding_prep_0 + 120
5 CoreFoundation 0x000000010248beaf CFDictionaryGetValue + 159
6 Foundation 0x0000000102befd78 -[NSKeyedUnarchiver initForReadingWithData:] + 1698
7 Foundation 0x0000000102c135ea +[NSKeyedUnarchiver unarchiveObjectWithData:] + 66
8 CoreData 0x000000010210b4e0 _prepareResultsFromResultSet + 3552
9 CoreData 0x0000000102108930 newFetchedRowsForFetchPlan_MT + 3296
10 CoreData 0x00000001020f53ac -[NSSQLCore objectsForFetchRequest:inContext:] + 524
11 CoreData 0x00000001020f4e2b -[NSSQLCore executeRequest:withContext:error:] + 299
12 CoreData 0x00000001021ca4f3 __65-[NSPersistentStoreCoordinator executeRequest:withContext:error:]_block_invoke + 3331
13 CoreData 0x00000001021d27ee gutsOfBlockToNSPersistentStoreCoordinatorPerform + 190
14 libdispatch.dylib 0x00000001052117f4 _dispatch_client_callout + 8
15 libdispatch.dylib 0x00000001051f8774 _dispatch_barrier_sync_f_invoke + 365
16 CoreData 0x00000001021c53d5 _perform + 197
17 CoreData 0x00000001020f4ac8 -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 504
18 CoreData 0x00000001020f33e0 -[NSManagedObjectContext executeFetchRequest:error:] + 544
19 LFDate 0x0000000101b9c3b3 _TFC6LFDate14DatabaseHelper7getUserfS0_FSSGSqCS_4User_ + 1075
20 LFDate 0x0000000101c4ce01 _TFC6LFDate23MenuTableViewController9tableViewfS0_FTCSo11UITableView21cellForRowAtIndexPathCSo11NSIndexPath_CSo15UITableViewCell + 4689
21 LFDate 0x0000000101c4e4ff _TToFC6LFDate23MenuTableViewController9tableViewfS0_FTCSo11UITableView21cellForRowAtIndexPathCSo11NSIndexPath_CSo15UITableViewCell + 79
22 UIKit 0x000000010349d4b3 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 508
23 UIKit 0x000000010347cfb1 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2846
24 UIKit 0x0000000103492e3c -[UITableView layoutSubviews] + 213
25 UIKit 0x000000010341f973 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 521
26 QuartzCore 0x000000010318ade8 -[CALayer layoutSublayers] + 150
27 QuartzCore 0x000000010317fa0e _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
28 QuartzCore 0x000000010317f87e _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
29 QuartzCore 0x00000001030ed63e _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
30 QuartzCore 0x00000001030ee74a _ZN2CA11Transaction6commitEv + 390
31 QuartzCore 0x00000001030eedb5 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 89
32 CoreFoundation 0x00000001024f7dc7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
33 CoreFoundation 0x00000001024f7d20 __CFRunLoopDoObservers + 368
34 CoreFoundation 0x00000001024edb53 __CFRunLoopRun + 1123
35 CoreFoundation 0x00000001024ed486 CFRunLoopRunSpecific + 470
36 GraphicsServices 0x00000001072f09f0 GSEventRunModal + 161
37 UIKit 0x00000001033a6420 UIApplicationMain + 1282
38 LFDate 0x0000000101be33ae top_level_code + 78
39 LFDate 0x0000000101be33ea main + 42
40 libdyld.dylib 0x0000000105246145 start + 1
41 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Parsing JSON and sometimes getting number instead of a string

I have an iPhone app which fetches user information (first name, last name, city) in JSON format from different social networks.
This works mostly well, but one of the social networks returns the city as a number instead of a string (actually I should made one more REST call to map this number to a city name... but for now I just want to display the number).
And when I try to display that number in a UILabel I get the exception (here fullscreen):
2014-02-15 11:24:16.194 MyAuth[8872:a0b] -[__NSCFNumber length]: unrecognized selector sent to instance 0xb074f90
2014-02-15 11:24:16.203 MyAuth[8872:a0b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFNumber length]: unrecognized selector sent to instance 0xb074f90'
*** First throw call stack:
(
0 CoreFoundation 0x01bb15e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x019348b6 objc_exception_throw + 44
2 CoreFoundation 0x01c4e903 -[NSObject(NSObject) doesNotRecognizeSelector:] + 275
3 CoreFoundation 0x01ba190b ___forwarding___ + 1019
4 CoreFoundation 0x01ba14ee _CF_forwarding_prep_0 + 14
5 Foundation 0x015798ed -[NSConcreteMutableAttributedString replaceCharactersInRange:withString:] + 39
6 Foundation 0x0157a55a -[NSConcreteMutableAttributedString initWithString:attributes:] + 293
7 UIKit 0x0084fbc6 -[UILabel _setText:] + 97
8 UIKit 0x0084fd84 -[UILabel setText:] + 40
9 MyAuth 0x0000a296 -[UserViewController viewDidLoad] + 678
10 UIKit 0x007b6318 -[UIViewController loadViewIfRequired] + 696
11 UIKit 0x007b65b4 -[UIViewController view] + 35
12 UIKit 0x007d03e2 -[UINavigationController _startCustomTransition:] + 778
13 UIKit 0x007dd0c7 -[UINavigationController _startDeferredTransitionIfNeeded:] + 688
14 UIKit 0x007ddcb9 -[UINavigationController __viewWillLayoutSubviews] + 57
15 UIKit 0x00917181 -[UILayoutContainerView layoutSubviews] + 213
16 UIKit 0x0070d267 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 355
17 libobjc.A.dylib 0x0194681f -[NSObject performSelector:withObject:] + 70
18 QuartzCore 0x054e12ea -[CALayer layoutSublayers] + 148
19 QuartzCore 0x054d50d4 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
20 QuartzCore 0x054d4f40 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26
21 QuartzCore 0x0543cae6 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 294
22 QuartzCore 0x0543de71 _ZN2CA11Transaction6commitEv + 393
23 QuartzCore 0x0543e544 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92
24 CoreFoundation 0x01b794ce __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
25 CoreFoundation 0x01b7941f __CFRunLoopDoObservers + 399
26 CoreFoundation 0x01b57344 __CFRunLoopRun + 1076
27 CoreFoundation 0x01b56ac3 CFRunLoopRunSpecific + 467
28 CoreFoundation 0x01b568db CFRunLoopRunInMode + 123
29 GraphicsServices 0x031a09e2 GSEventRunModal + 192
30 GraphicsServices 0x031a0809 GSEventRun + 104
31 UIKit 0x006a2d3b UIApplicationMain + 1225
32 MyAuth 0x0000ab7d main + 141
33 libdyld.dylib 0x02518725 start + 0
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
So I go to my JSON parsing code:
- (User*)createUserFromJson:(id)json
{
if (![json isKindOfClass:[NSDictionary class]]) {
NSLog(#"Parsing response failed");
return nil;
}
NSDictionary *dict = json[#"response"][0];
User *user = [[User alloc] init];
user.key = kVK;
user.userId = dict[#"uid"];
user.firstName = dict[#"first_name"];
user.lastName = dict[#"last_name"];
user.city = dict[#"city"]; // THE PROBLEMATIC LINE
user.avatar = dict[#"photo_big"];
user.female = (2 == [dict[#"female"] intValue]);
return user;
}
and try to change it to:
user.city = [NSString stringWithFormat:#"%d", dict[#"city"]];
but then I get the compile-time warning (here fullscreen):
Format specifies type 'int' but the argument has type 'id'
So my question is how to solve this issue cleanly (w/o Xcode warnings) and robust (when fetched JSON data happens to be a string)?
The fastest solution is:
[NSString stringWithFormat:#"%#", dict[#"city"]];
which will take the description of the string or the number and convert that into a string.
In the future you may want to use:
if ([1dict[#"city"] isKindOfClass:[NSNumber class]]) { ...
to check what you have received and work with it specifically. i.e. to do your lookup and to not use stringWithFormat: when you actually already have a string (because it's inefficient).

Deleting object in background moc then refreshing it in main moc causes crash in NSFetchedResultsController update

I encountered an NSObjectInaccessibleException that I can not understand:
*** Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0x8c40040 <x-coredata://85B02C1C-1FFC-4CBF-B7AC-EEA259115427/Event/p6>''
*** First throw call stack:
(
0 CoreFoundation 0x01aa15e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x018248b6 objc_exception_throw + 44
2 CoreData 0x0025733b _PFFaultHandlerLookupRow + 2715
3 CoreData 0x00256897 -[NSFaultHandler fulfillFault:withContext:forIndex:] + 39
4 CoreData 0x00256473 _PF_FulfillDeferredFault + 259
5 CoreData 0x002562c6 _sharedIMPL_pvfk_core + 70
6 CoreData 0x0025acd5 -[NSManagedObject(_PFDynamicAccessorsAndPropertySupport) _genericValueForKey:withIndex:flags:] + 85
7 CoreData 0x00294781 _PF_Handler_Public_GetProperty + 161
8 CoreData 0x00294685 -[NSManagedObject valueForKey:] + 149
9 Foundation 0x01471a5a -[NSObject(NSKeyValueCoding) valueForKeyPath:] + 409
10 Foundation 0x015079ba -[NSSortDescriptor compareObject:toObject:] + 166
11 CoreData 0x00366175 +[NSFetchedResultsController(PrivateMethods) _insertIndexForObject:inArray:lowIdx:highIdx:sortDescriptors:] + 309
12 CoreData 0x00360f61 -[NSFetchedResultsController(PrivateMethods) _postprocessInsertedObjects:] + 737
13 CoreData 0x00362c44 -[NSFetchedResultsController(PrivateMethods) _postprocessUpdatedObjects:] + 916
14 CoreData 0x00363578 -[NSFetchedResultsController(PrivateMethods) _managedObjectContextDidChange:] + 2152
15 Foundation 0x014f7bf9 __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke + 40
16 CoreFoundation 0x01afd524 __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 20
17 CoreFoundation 0x01a5500b _CFXNotificationPost + 2859
18 Foundation 0x01431951 -[NSNotificationCenter postNotificationName:object:userInfo:] + 98
19 CoreData 0x00268173 -[NSManagedObjectContext(_NSInternalNotificationHandling) _postObjectsDidChangeNotificationWithUserInfo:] + 83
20 CoreData 0x0030778f -[NSManagedObjectContext(_NSInternalChangeProcessing) _createAndPostChangeNotification:withDeletions:withUpdates:withRefreshes:] + 367
21 CoreData 0x00263e38 -[NSManagedObjectContext(_NSInternalChangeProcessing) _postRefreshedObjectsNotificationAndClearList] + 136
22 CoreData 0x002639e4 -[NSManagedObjectContext(_NSInternalChangeProcessing) _processRecentChanges:] + 3140
23 CoreData 0x00262d99 -[NSManagedObjectContext processPendingChanges] + 41
24 CoreData 0x00236fe1 _performRunLoopAction + 321
25 CoreFoundation 0x01a694ce __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
26 CoreFoundation 0x01a6941f __CFRunLoopDoObservers + 399
27 CoreFoundation 0x01a47344 __CFRunLoopRun + 1076
28 CoreFoundation 0x01a46ac3 CFRunLoopRunSpecific + 467
29 CoreFoundation 0x01a468db CFRunLoopRunInMode + 123
30 GraphicsServices 0x039029e2 GSEventRunModal + 192
31 GraphicsServices 0x03902809 GSEventRun + 104
32 UIKit 0x00592d3b UIApplicationMain + 1225
33 RefreshDeletedTest 0x00005d9d main + 141
34 libdyld.dylib 0x020df70d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type _NSCoreDataException
It is caused by a specific code flow:
- (void)deleteObject:(NSManagedObject *)object {
NSManagedObjectID *objID = object.objectID;
NSManagedObjectContext *dataProcessingMoc = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
dataProcessingMoc.persistentStoreCoordinator = self.managedObjectContext.persistentStoreCoordinator;
dataProcessingMoc.mergePolicy = NSMergeByPropertyObjectTrumpMergePolicy;
[[NSNotificationCenter defaultCenter] addObserver:self selector:#selector(dataProcessingContextDidSave:) name:NSManagedObjectContextDidSaveNotification object:dataProcessingMoc];
// If I use performBlockAndWait: instead of performBlock: the issue goes away.
[dataProcessingMoc performBlock:^{
NSManagedObject *objInDPMoc = [dataProcessingMoc objectWithID:objID];
NSLog(#"Delete: %#", objInDPMoc);
[dataProcessingMoc deleteObject:objInDPMoc]; // 1
[object.managedObjectContext performBlockAndWait:^{
[object.managedObjectContext refreshObject:object mergeChanges:NO]; // 2
}];
[dataProcessingMoc save:NULL]; // 3
}];
}
- (void)dataProcessingContextDidSave:(NSNotification *)note {
NSManagedObjectContext *moc = self.managedObjectContext;
[moc performBlockAndWait:^{ // 3
[moc mergeChangesFromContextDidSaveNotification:note];
NSError *error;
if ([moc hasChanges] && ![moc save:&error]) {
NSLog(#"Unresolved error %#", error);
abort();
}
}];
}
Note: the code must look weird and does not make much sense. It is the result of my reducing real code to the minimum bug-reproducing code.
Delete an object in background moc.
Refresh the same object to turned into a fault in main moc.
Save background moc and merge its changes to main moc using NSManagedObjectContextDidSaveNotification.
The exception occurs before the real merge, at the main moc's call of performBlockAndWait:.
Here is the background moc's thread stack at the time of crash:
#0 0x02210fb6 in semaphore_wait_trap ()
#1 0x01e3ccde in _dispatch_thread_semaphore_wait ()
#2 0x01e3a516 in _dispatch_barrier_sync_f_slow ()
#3 0x01e3a413 in dispatch_barrier_sync_f ()
#4 0x0028bf1f in -[NSManagedObjectContext performBlockAndWait:] ()
#5 0x000037b5 in -[MasterViewController dataProcessingContextDidSave:] at /Users/an0/dev/Projects/iOS/Study/RefreshDeletedTest/RefreshDeletedTest/MasterViewController.m:84
#6 0x014f7bf9 in __57-[NSNotificationCenter addObserver:selector:name:object:]_block_invoke ()
#7 0x01afd524 in __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ ()
#8 0x01a5500b in _CFXNotificationPost ()
#9 0x01431951 in -[NSNotificationCenter postNotificationName:object:userInfo:] ()
#10 0x0027bb2c in -[NSManagedObjectContext(_NSInternalAdditions) _didSaveChanges] ()
#11 0x0026720f in -[NSManagedObjectContext save:] ()
#12 0x0000345a in __37-[MasterViewController cleanObjects:]_block_invoke at /Users/an0/dev/Projects/iOS/Study/RefreshDeletedTest/RefreshDeletedTest/MasterViewController.m:78
#13 0x003047c3 in developerSubmittedBlockToNSManagedObjectContextPerform_privateasync ()
#14 0x01e4d4b0 in _dispatch_client_callout ()
#15 0x01e3b07f in _dispatch_queue_drain ()
#16 0x01e3ae7a in _dispatch_queue_invoke ()
#17 0x01e3be1f in _dispatch_root_queue_drain ()
#18 0x01e3c137 in _dispatch_worker_thread2 ()
#19 0x021d9dab in _pthread_wqthread ()
Why it crashes this way? Is my code really wrong or it is a bug of Core Data?
Another odd thing that I can not understand is that, after such a crash the app can not be launch any more for it will crash on launch:
2014-01-05 12:31:34.151 RefreshDeletedTest[3546:70b] *** Terminating app due to uncaught exception 'NSObjectInaccessibleException', reason: 'CoreData could not fulfill a fault for '0xa88d060 <x-coredata://93009ECF-EC6E-4B12-BC40-997C4BF3B8DF/Event/p11>''
*** First throw call stack:
(
0 CoreFoundation 0x01aa05e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x018238b6 objc_exception_throw + 44
2 CoreData 0x0025633b _PFFaultHandlerLookupRow + 2715
3 CoreData 0x00255897 -[NSFaultHandler fulfillFault:withContext:forIndex:] + 39
4 CoreData 0x00255473 _PF_FulfillDeferredFault + 259
5 CoreData 0x002552c6 _sharedIMPL_pvfk_core + 70
6 CoreData 0x00259cd5 -[NSManagedObject(_PFDynamicAccessorsAndPropertySupport) _genericValueForKey:withIndex:flags:] + 85
7 CoreData 0x00293781 _PF_Handler_Public_GetProperty + 161
8 CoreData 0x00293685 -[NSManagedObject valueForKey:] + 149
9 Foundation 0x014a8f0a -[NSArray(NSKeyValueCoding) valueForKey:] + 456
10 Foundation 0x01470a5a -[NSObject(NSKeyValueCoding) valueForKeyPath:] + 409
11 Foundation 0x0149b99d -[NSArray(NSKeyValueCoding) valueForKeyPath:] + 580
12 CoreData 0x0035b7e9 -[NSFetchedResultsController performFetch:] + 697
13 RefreshDeletedTest 0x00003910 -[MasterViewController fetchedResultsController] + 800
14 RefreshDeletedTest 0x0000307e -[MasterViewController numberOfSectionsInTableView:] + 78
15 UIKit 0x007e5b94 -[UITableViewRowData(UITableViewRowDataPrivate) _updateNumSections] + 102
16 UIKit 0x007e6993 -[UITableViewRowData invalidateAllSections] + 69
17 UIKit 0x0065d237 -[UITableView _updateRowData] + 194
18 UIKit 0x0065d170 -[UITableView _ensureRowDataIsLoaded] + 45
19 UIKit 0x006704b3 -[UITableView numberOfSections] + 35
20 UIKit 0x0084d3d3 -[UITableViewController viewWillAppear:] + 103
21 UIKit 0x006a8bfa -[UIViewController _setViewAppearState:isAnimating:] + 419
22 UIKit 0x006a9108 -[UIViewController __viewWillAppear:] + 114
23 UIKit 0x006cb3f5 -[UINavigationController _startTransition:fromViewController:toViewController:] + 800
24 UIKit 0x006cc09c -[UINavigationController _startDeferredTransitionIfNeeded:] + 645
25 UIKit 0x006cccb9 -[UINavigationController __viewWillLayoutSubviews] + 57
26 UIKit 0x00806181 -[UILayoutContainerView layoutSubviews] + 213
27 UIKit 0x0e35656f -[UILayoutContainerViewAccessibility(SafeCategory) layoutSubviews] + 50
28 UIKit 0x005fc267 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 355
29 libobjc.A.dylib 0x0183581f -[NSObject performSelector:withObject:] + 70
30 QuartzCore 0x045802ea -[CALayer layoutSublayers] + 148
31 QuartzCore 0x045740d4 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
32 QuartzCore 0x04580235 -[CALayer layoutIfNeeded] + 160
33 UIKit 0x006b7613 -[UIViewController window:setupWithInterfaceOrientation:] + 304
34 UIKit 0x005d6177 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] + 5212
35 UIKit 0x005d4d16 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 82
36 UIKit 0x005d4be8 -[UIWindow _setRotatableViewOrientation:updateStatusBar:duration:force:] + 117
37 UIKit 0x005d4c70 -[UIWindow _setRotatableViewOrientation:duration:force:] + 67
38 UIKit 0x005d3d0a __57-[UIWindow _updateToInterfaceOrientation:duration:force:]_block_invoke + 120
39 UIKit 0x005d3c6c -[UIWindow _updateToInterfaceOrientation:duration:force:] + 400
40 UIKit 0x005d49c3 -[UIWindow setAutorotates:forceUpdateInterfaceOrientation:] + 870
41 UIKit 0x005d7fb6 -[UIWindow setDelegate:] + 449
42 UIKit 0x006a9737 -[UIViewController _tryBecomeRootViewControllerInWindow:] + 180
43 UIKit 0x005cdc1c -[UIWindow addRootViewControllerViewIfPossible] + 609
44 UIKit 0x005cdd97 -[UIWindow _setHidden:forced:] + 312
45 UIKit 0x005ce02d -[UIWindow _orderFrontWithoutMakingKey] + 49
46 UIKit 0x0e332c66 -[UIWindowAccessibility(SafeCategory) _orderFrontWithoutMakingKey] + 77
47 UIKit 0x005d889a -[UIWindow makeKeyAndVisible] + 65
48 UIKit 0x0058bcd0 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1851
49 UIKit 0x005903a8 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 824
50 UIKit 0x005a487c -[UIApplication handleEvent:withNewEvent:] + 3447
51 UIKit 0x005a4de9 -[UIApplication sendEvent:] + 85
52 UIKit 0x00592025 _UIApplicationHandleEvent + 736
53 GraphicsServices 0x039032f6 _PurpleEventCallback + 776
54 GraphicsServices 0x03902e01 PurpleEventCallback + 46
55 CoreFoundation 0x01a1bd65 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
56 CoreFoundation 0x01a1ba9b __CFRunLoopDoSource1 + 523
57 CoreFoundation 0x01a4677c __CFRunLoopRun + 2156
58 CoreFoundation 0x01a45ac3 CFRunLoopRunSpecific + 467
59 CoreFoundation 0x01a458db CFRunLoopRunInMode + 123
60 UIKit 0x0058fadd -[UIApplication _run] + 840
61 UIKit 0x00591d3b UIApplicationMain + 1225
62 RefreshDeletedTest 0x0000508d main + 141
63 libdyld.dylib 0x020de70d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type _NSCoreDataException
Here is the sample project that you can run to see the issues yourself: http://d.pr/f/y3VQ
In a multithreaded environment there is no way to avoid this issue.
As long as you have 2 different contexts on the same hierarchy level (be it parent child architecture or directly connected to the store) you might encounter a situation where one context deleted an object (and committed changes to the store) and the other one try to access this object before changes were merged.
This might also happen when parent context commit changes to the store and its child try to access deleted items he hold as faults.
In general, in every place where changes are not propagated automatically between contexts prior to a commit, there is a chance to get this exception.
If you can pipeline your contexts (store-context1-context2-...) and only delete from the final context in the chain you can avoid this issue.
You can devise some algorithm to delay your delete operations so they are committed only when no other context use a specific item, but this involves a lot of bookkeeping on your part.
You can reduce conflicts between your context by fetching full fledged (no faults) objects, or the entire sub-graph you will be working on (cannot be done when using FRC) and make your operations on these objects.
This was addressed in WWDC 2015 220 What's New in Core Data with release of iOS 9 and the shouldDeleteInaccessibleFaults property on NSManagedObjectContext.
Currently, shouldDeleteInaccessibleFaults defaults to yes.
If we encounter a fault we'll mark the fault as deleted and any missing attributes will be null, nil or zero.
This allows your app to continue on with this object and treat it as a deleted object.
No longer will you crash but you'll be able to merely keep going on and show the user what they have expected to see.

Handling Compatibility issues IOS 4.0- 5.1

I have created an app that is running great on 5.0 and above but when I test on devices lower I have ran into a few issues that I am unsure of how to tackle and correct.
The first big issue is when saving to core data I use a error method that I believe is apples default error method that is created when you make a core data model. The app just crashes when below 5.0 but if I block out the error code everything works fine. Below is the code used to find and error and handle it.
NSError *error;
if (![managedObjectContext save:&error]) { // crash here
// This is a serious error saying the record could not be saved.
// Advise the user to restart the application
}
//crash log below
2012-05-13 10:17:22.062 PreviewMaker[41595:207] -[UIImage encodeWithCoder:]:
unrecognized selector sent to instance 0x5e7ce80
2012-05-13 10:17:22.064 PreviewMaker[41595:207] *** Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: '-[UIImage encodeWithCoder:]:
unrecognized selector sent to instance 0x5e7ce80'
*** Call stack at first throw:
(
0 CoreFoundation 0x013fc5a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x0178b313 objc_exception_throw + 44
2 CoreFoundation 0x013fe0bb -[NSObject(NSObject)
doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x0136d966 ___forwarding___ + 966
4 CoreFoundation 0x0136d522 _CF_forwarding_prep_0 + 50
5 Foundation 0x00c45b3e _encodeObject + 1076
6 Foundation 0x00c50f89 +[NSKeyedArchiver
archivedDataWithRootObject:] + 206
7 CoreData 0x01122cb5 -[NSSQLiteConnection execute] +
2677
8 CoreData 0x011771d6 -[NSSQLiteConnection insertRow:]
+ 262
9 CoreData 0x01173e64 -[NSSQLConnection
performAdapterOperations:] + 180
10 CoreData 0x01173b0e -[NSSQLCore
_performChangesWithAdapterOps:] + 494
11 CoreData 0x011725ea -[NSSQLCore performChanges] + 410
12 CoreData 0x0116c038 -[NSSQLCore saveChanges:] + 216
13 CoreData 0x0112a199 -[NSSQLCore
executeRequest:withContext:error:] + 409
14 CoreData 0x011da70b -[NSPersistentStoreCoordinator
executeRequest:withContext:error:] + 3691
15 CoreData 0x01162948 -[NSManagedObjectContext save:] +
712
16 PreviewMaker 0x0000a0c0 -[MainViewController
noUploadJustSaveImage:] + 331
17 PreviewMaker 0x00009d3c -[MainViewController
UserConfirmedToSaveImage] + 756
18 UIKit 0x004774fd -[UIApplication
sendAction:to:from:forEvent:] + 119
19 UIKit 0x00507799 -[UIControl
sendAction:to:forEvent:] + 67
20 UIKit 0x00509c2b -[UIControl(Internal)
_sendActionsForEvents:withEvent:] + 527
21 UIKit 0x005087d8 -[UIControl
touchesEnded:withEvent:] + 458
22 UIKit 0x0049bded -[UIWindow _sendTouchesForEvent:]
+ 567
23 UIKit 0x0047cc37 -[UIApplication sendEvent:] + 447
24 UIKit 0x00481f2e _UIApplicationHandleEvent + 7576
25 GraphicsServices 0x01eb8992 PurpleEventCallback + 1550
26 CoreFoundation 0x013dd944
__CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
27 CoreFoundation 0x0133dcf7 __CFRunLoopDoSource1 + 215
28 CoreFoundation 0x0133af83 __CFRunLoopRun + 979
29 CoreFoundation 0x0133a840 CFRunLoopRunSpecific + 208
30 CoreFoundation 0x0133a761 CFRunLoopRunInMode + 97
31 GraphicsServices 0x01eb71c4 GSEventRunModal + 217
32 GraphicsServices 0x01eb7289 GSEventRun + 115
33 UIKit 0x00485c93 UIApplicationMain + 1160
34 PreviewMaker 0x00002e07 main + 121
35 PreviewMaker 0x00002d85 start + 53
)
terminate called after throwing an instance of 'NSException'
Another issue I am running into is setting tintColor on UI objects such as the UISwitch. I have a settings controller that has several UISwitches and such which just about all have a tint color set on, but once agin anything below 5.0 crashes. How can I handle the two and not have to re-write the code just to be compatible with devices below 5.0.
shineSwitch = [[[UISwitch alloc] initWithFrame:CGRectZero] autorelease];
[cell.contentView addSubview:shineSwitch];
cell.accessoryView = shineSwitch;
[shineSwitch addTarget:self action:#selector(switchChanged:) 
forControlEvents:UIControlEventValueChanged];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
shineSwitch.onTintColor = [UIColor colorWithRed:0.0 green:0.61 blue:0.99 alpha:1.0];
//crash Log below
2012-05-13 10:19:45.033 PreviewMaker[41611:207] -[UISwitch setOnTintColor:]:
unrecognized selector sent to instance 0x5eab860
2012-05-13 10:19:45.034 PreviewMaker[41611:207] *** Terminating app due to uncaught
exception 'NSInvalidArgumentException', reason: '-[UISwitch setOnTintColor:]:
unrecognized selector sent to instance 0x5eab860'
*** Call stack at first throw:
(
0 CoreFoundation 0x013fc5a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x0178b313 objc_exception_throw + 44
2 CoreFoundation 0x013fe0bb -[NSObject(NSObject)
doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x0136d966 ___forwarding___ + 966
4 CoreFoundation 0x0136d522 _CF_forwarding_prep_0 + 50
5 PreviewMaker 0x0000f6fb -[FlipsideViewController
tableView:cellForRowAtIndexPath:] + 1353
6 UIKit 0x004ecb98 -
[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 634
7 UIKit 0x004e24cc -
[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] + 75
8 UIKit 0x004f78cc -
[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] + 1561
9 UIKit 0x004ef90c -[UITableView layoutSubviews] +
242
10 QuartzCore 0x001e2a5a -[CALayer layoutSublayers] + 181
11 QuartzCore 0x001e4ddc CALayerLayoutIfNeeded + 220
12 QuartzCore 0x0018a0b4
_ZN2CA7Context18commit_transactionEPNS_11TransactionE + 310
13 QuartzCore 0x0018b294 _ZN2CA11Transaction6commitEv +
292
14 QuartzCore 0x0018b46d
_ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 99
15 CoreFoundation 0x013dd89b
__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
16 CoreFoundation 0x013726e7 __CFRunLoopDoObservers + 295
17 CoreFoundation 0x0133b1d7 __CFRunLoopRun + 1575
18 CoreFoundation 0x0133a840 CFRunLoopRunSpecific + 208
19 CoreFoundation 0x0133a761 CFRunLoopRunInMode + 97
20 GraphicsServices 0x01eb71c4 GSEventRunModal + 217
21 GraphicsServices 0x01eb7289 GSEventRun + 115
22 UIKit 0x00485c93 UIApplicationMain + 1160
23 PreviewMaker 0x00002e07 main + 121
24 PreviewMaker 0x00002d85 start + 53
)
terminate called after throwing an instance of 'NSException'
Any help would be greatly appreciated!

Resources