iOS crash with Core Data - ios

when I execute this line of code in iOS 8.3 this line crashes:
NSArray *results = [self executeFetchRequest:request inContext:context];
here is the entire function which fails:
+ (id) executeFetchRequestAndReturnFirstObject:(NSFetchRequest *)request inContext:(NSManagedObjectContext *)context
{
[request setFetchLimit:1];
NSArray *results = [self executeFetchRequest:request inContext:context];
if ([results count] == 0)
{
return nil;
}
return [results objectAtIndex:0];
}
the above function is called by:
+ (id)findFirstByAttribute:(NSString *)attribute withValue:(id)searchValue inContext:(NSManagedObjectContext *)context
{
NSFetchRequest *request = [self requestFirstByAttribute:attribute withValue:searchValue inContext:context];
[request setPropertiesToFetch:[NSArray arrayWithObject:attribute]];
return [self executeFetchRequestAndReturnFirstObject:request inContext:context];
}
It is worth noting that I am very new to iOS programming so please go easy on me, the question may not be the best and there may not be much backing code but this is due to my lack of knowledge in iOS. My android questions are generally much better than this :P If I am able to add any more detail, I will add more as I can, the crash log is below
* Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Bad fetch request
(NSManagedObjectResultType not compatible with contents of
propertiesToFetch)'
* First throw call stack: ( 0 CoreFoundation 0x0000000111d7dc65 exceptionPreprocess + 165 1 libobjc.A.dylib
0x0000000110fafbb7 objc_exception_throw + 45 2 CoreData
0x00000001112ecb6e -[NSSQLGenerator
newSQLStatementForRequest:ignoreInheritance:countOnly:nestingLevel:] +
1646 3 CoreData 0x00000001112d8dc4
-[NSSQLAdapter _statementForFetchRequest:ignoreInheritance:countOnly:nestingLevel:] + 244 4 CoreData 0x00000001111f0e0c
-[NSSQLAdapter _newSelectStatementWithFetchRequest:ignoreInheritance:] + 316 5 CoreData 0x00000001111f0a86 -[NSSQLCore newRowsForFetchPlan:] + 118 6 CoreData 0x00000001111f033c -[NSSQLCore objectsForFetchRequest:inContext:] +
524 7 CoreData 0x00000001111efdbb
-[NSSQLCore executeRequest:withContext:error:] + 299 8 CoreData 0x00000001112caa6c __65-[NSPersistentStoreCoordinator
executeRequest:withContext:error:]_block_invoke + 3356 9 CoreData
0x00000001112d3c30 gutsOfBlockToNSPersistentStoreCoordinatorPerform +
192 10 libdispatch.dylib 0x0000000114e29614
_dispatch_client_callout + 8 11 libdispatch.dylib 0x0000000114e0f002 _dispatch_barrier_sync_f_invoke + 365 12 CoreData
0x00000001112c5245 _perform + 197 13 CoreData
0x00000001111efa58 -[NSPersistentStoreCoordinator
executeRequest:withContext:error:] + 504 14 CoreData
0x00000001111ee2ca -[NSManagedObjectContext
executeFetchRequest:error:] + 586 15 HawkExpress
0x000000010e52438e +[NSManagedObject(MagicalRecord)
executeFetchRequest:inContext:] + 62 16 HawkExpress
0x000000010e52446e +[NSManagedObject(MagicalRecord)
executeFetchRequestAndReturnFirstObject:inContext:] + 78 17
HawkExpress 0x000000010e5261fc
+[NSManagedObject(MagicalRecord) findFirstByAttribute:withValue:inContext:] + 140 18 HawkExpress
0x000000010e526274 +[NSManagedObject(MagicalRecord)
findFirstByAttribute:withValue:] + 100 19 HawkExpress
0x000000010e52aa54 +[FavouritesManager doesFavouriteExist:] + 84 20
HawkExpress 0x000000010e4de4a7
-[BookCabViewController tableView:cellForRowAtIndexPath:] + 2087 21 UIKit 0x00000001124b9a28 -[UITableView
_createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 508 22 UIKit 0x0000000112498248 -[UITableView
_updateVisibleCellsNow:isRecursive:] + 2853 23 UIKit 0x00000001124ae8a9 -[UITableView layoutSubviews] + 210 24 UIKit
0x0000000112438a2b -[UIView(CALayerDelegate) layoutSublayersOfLayer:]
+ 536 25 QuartzCore 0x000000010fdfbec2 -[CALayer layoutSublayers] + 146 26 QuartzCore 0x000000010fdf06d6 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE +
380 27 QuartzCore 0x000000010fdf0546
_ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24 28 QuartzCore 0x000000010fd5c886
_ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242 29 QuartzCore 0x000000010fd5da3a
_ZN2CA11Transaction6commitEv + 462 30 QuartzCore 0x000000010fd5e0eb
_ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 89 31 CoreFoundation 0x0000000111cb0ca7
__CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION + 23 32 CoreFoundation 0x0000000111cb0c00
__CFRunLoopDoObservers + 368 33 CoreFoundation 0x0000000111ca6a33 __CFRunLoopRun + 1123 34 CoreFoundation
0x0000000111ca6366 CFRunLoopRunSpecific + 470 35 GraphicsServices
0x0000000114a34a3e GSEventRunModal + 161 36 UIKit
0x00000001123b8900 UIApplicationMain + 1282 37 HawkExpress
0x000000010e4baa23 main + 99 38 libdyld.dylib
0x0000000114e5d145 start + 1 ) libc++abi.dylib: terminating with
uncaught exception of type NSException (lldb)

You need to check if the NSArray results is nil before you can do a count.
if (array != nil) {
NSUInteger count = [array count]; // May be 0 if the object has been deleted.
//
}
else {
// Deal with error.
}
See https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/CoreData/Articles/cdFetching.html

Your NSFetchRequest object is probably not constructed correctly.
Here is a valid NSFetchRequest example. Find plenty more by googling "NSFetchRequest example".
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"name == %#", aTitle]; //<----- (a)
[request setEntity:[NSEntityDescription entityForName:#"Person" inManagedObjectContext:moc]];
[request setPredicate:predicate];
Be careful at (a), the string must strictly follow the predicate format string pattern (see NSPrediate class reference), name must be a property of Person entity in your managed object model
And the problem is in this part
NSFetchRequest *request = [self requestFirstByAttribute:attribute withValue:searchValue inContext:context];
[request setPropertiesToFetch:[NSArray arrayWithObject:attribute]];
So, post the code for method [self requestFirstByAttribute... ] if still not resolved.

tried to comment out the line [request setPropertiesToFetch:[NSArray arrayWithObject:attribute]];?
'Bad fetch request (NSManagedObjectResultType not compatible with contents of propertiesToFetch)' means, that you seem to expect the default NSFetchRequestResultType (NSManagedObjectResultType). But you request not to fetch the complete Entity, but only ONE attribute (why, just by the way? Your method provide an expected value and gives only one attribute to fetch).
My solution to this:
- (id)findEntityNamed:(NSString*)entity withKeyPath:(NSString*)path equalTo:(id)value
{
NSFetchRequest* fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:entity
inManagedObjectContext:context]];
NSPredicate* predicate =
[NSComparisonPredicate predicateWithLeftExpression:[NSExpression expressionForKeyPath:path]
rightExpression:[NSExpression expressionForConstantValue:value]
modifier:NSDirectPredicateModifier
type:NSEqualToPredicateOperatorType
options:0];
[fetchRequest setPredicate:predicate];
[fetchRequest setFetchLimit:1]; // ONLY 1 OBJECT IS FETCHED!
NSError* err = nil;
NSArray* results = [context executeFetchRequest:fetchRequest error:&err];
[fetchRequest release];
if( err )
{
// do logging stuff etc.
}
if( [results count] < 1 )
return nil;
return [results lastObject];
}
you can try this and tell if this is more like you was looking for

Related

libobjc.A.dylib objc_msgSend crash occurring with core data usage in background thread

I'm looking into a somewhat frequent crash reported in my application's Crashlytics console.
One of the many examples I have has the following crashed thread stacktrace:
#11. Crashed: com.apple.root.default-qos
0 libobjc.A.dylib 0x22f3fa86 objc_msgSend + 5
1 Foundation 0x23ee3005 -[NSString caseInsensitiveCompare:] + 28
2 Foundation 0x23ed10bd _NSCompareObject + 28
3 Foundation 0x23ed109d _NSSortFunctionOne + 120
4 CoreFoundation 0x2373e6a3 __CFSimpleMergeSort + 114
5 CoreFoundation 0x2373e6c5 __CFSimpleMergeSort + 148
6 CoreFoundation 0x2373e6d9 __CFSimpleMergeSort + 168
7 CoreFoundation 0x2373e6c5 __CFSimpleMergeSort + 148
8 CoreFoundation 0x2373e6d9 __CFSimpleMergeSort + 168
9 CoreFoundation 0x2368ac35 CFSortIndexes + 404
10 CoreFoundation 0x2368c241 CFMergeSortArray + 176
11 Foundation 0x23ed0a9d _sortedObjectsUsingDescriptors + 456
12 Foundation 0x23f9c9fb -[NSSet(NSKeyValueSorting) sortedArrayUsingDescriptors:] + 510
13 MyApp 0x6d431 __24-[MyApp refresh]_block_invoke (MyApp.m:247)
14 CoreFoundation 0x23769499 __NSArrayEnumerate + 372
15 CoreFoundation 0x236e6c3b -[NSArray enumerateObjectsWithOptions:usingBlock:] + 62
16 MyApp 0x6d17d -[MyApp refresh] (MyApp.m:263)
17 MyApp 0xa97eb __52-[MyAppRequest updateAfterNotification:]_block_invoke (MyAppRequest.m:1175)
18 libdispatch.dylib 0x23307cbf _dispatch_call_block_and_release + 10
19 libdispatch.dylib 0x233136a1 _dispatch_root_queue_drain + 1572
20 libdispatch.dylib 0x2331307b _dispatch_worker_thread3 + 94
21 libsystem_pthread.dylib 0x234a6e0d _pthread_wqthread + 1024
22 libsystem_pthread.dylib 0x234a69fc start_wqthread + 8
Other instances of the crash occur in the same app code (in the refresh method of MyApp class), but during different parts of the CoreFoundation sortedArrayUsingDescriptors method logic. For example, another crash example stacktrace has:
0 libobjc.A.dylib 0x1823cdb90 objc_msgSend + 16
1 CoreFoundation 0x182c42738 CFStringCompareWithOptionsAndLocale + 232
2 Foundation 0x183644840 _NSCompareObject + 64
3 CoreFoundation 0x182d150f4 __CFSimpleMergeSort + 196
4 CoreFoundation 0x182d15124 __CFSimpleMergeSort + 244
5 CoreFoundation 0x182d15124 __CFSimpleMergeSort + 244
6 CoreFoundation 0x182d15124 __CFSimpleMergeSort + 244
7 CoreFoundation 0x182d1513c __CFSimpleMergeSort + 268
8 CoreFoundation 0x182d15124 __CFSimpleMergeSort + 244
9 CoreFoundation 0x182d15124 __CFSimpleMergeSort + 244
10 CoreFoundation 0x182d15124 __CFSimpleMergeSort + 244
11 CoreFoundation 0x182c3b738 CFSortIndexes + 472
12 CoreFoundation 0x182c3cf58 CFMergeSortArray + 220
13 Foundation 0x1836440f8 _sortedObjectsUsingDescriptors + 564
14 Foundation 0x183725120 -[NSSet(NSKeyValueSorting) sortedArrayUsingDescriptors:] + 564
15 MyApp 0x10006f264 __24-[MyApp refresh]_block_invoke (MyApp.m:247)
The app code in refresh is:
- (void)refresh {
NSArray *products = [self getProducts];
NSMutableArray *validProducts = [NSMutableArray array];
[products enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
Product *prod = obj;
// Convert to internal native format (MyAppProduct) for business reasons...
MyAppProduct *myAppProd = [[MyAppProduct alloc] init];
myAppProd.ID = prod.id;
myAppProd.name = prod.name;
NSArray *subProds = [prod.subProds sortedArrayUsingDescriptors:#[[NSSortDescriptor sortDescriptorWithKey:#"subProds" ascending:NO]]];
NSMutableArray *validSubProds = [NSMutableArray array];
[subProds enumerateObjectsUsingBlock:^(id _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
SubProd *subProd = obj;
// Convert to internal native format (MyAppSubProduct) for business reasons...
MyAppSubProduct *myAppSubProd = [[MyAppSubProduct alloc] initWithSubProd:subProd];
[validSubProds addObject:myAppSubProd];
}];
myAppProd.subProds = validSubProds;
myAppProd.count = [product.count integerValue];
// Add to array
[validProducts addObject:myAppProd];
}];
// Apply array to self
_products = validProducts
}
where getProducts is:
- (NSArray*)getProducts {
NSFetchRequest *productFetchRequest = [NSFetchRequest fetchRequestWithEntityName:#"Products"];
// Filter
NSMutableArray *productsPredicates = [NSMutableArray array];
[productsPredicates addObject:[NSPredicate predicateWithFormat:#"life_uid == %#", req.lifeUid]];
[productsPredicates addObject:[NSPredicate predicateWithFormat:#"hidden == %#", #NO]];
[productFetchRequest setPredicate:[NSCompoundPredicate andPredicateWithSubpredicates:productsPredicates]];
// Sort
NSSortDescriptor *sortProductsByName = [NSSortDescriptor sortDescriptorWithKey:#"name" ascending:YES];
[productFetchRequest setSortDescriptors:#[sortProductsByName]];
[productFetchRequest setReturnsObjectsAsFaults:NO];
[productFetchRequest setRelationshipKeyPathsForPrefetching:#[#"subprods", #"subprods.special"]];
NSManagedObjectContext *moc = [MyAppCoreDataController sharedController].mainManagedObjectContext;
NSError *error = nil;
NSArray *products = [moc executeFetchRequest:productFetchRequest error:&error];
if (error) {
NSLog(#"Error fetching products %#", error);
}
return products;
}
And refresh is being called like so:
- (void)updateAfterNotification:(NSNotification *)notification {
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[MyApp instance] refresh];
});
}
Most likely it's because you're not handling Core Data concurrency correctly. When you create a managed object context using NSPrivateQueueConcurrencyType or NSMainQueueConcurrencyType, you must put all Core Data access inside a call to performBlock or performBlockAndWait. That includes fetches as well as accessing attribute values of fetched objects.
You're using dispatch_async, which is not the right way to handle concurrency with Core Data. You should switch to using performBlock or performBlockAndWait.

Thread : 1 EXC_BAD_ACCESS occurs in the NSPredicate

In my mac OS X application, I am getting this EXC_BAD_ACCESS signal in Core Data part (NSPredicate).
Code for reference:
[self.managedObjectContext reset];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[self.managedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
//Setting Entity to be Queried
NSEntityDescription *entity = [NSEntityDescription entityForName:#"FileTable"
inManagedObjectContext:self.managedObjectContext];
[fetchRequest setSortDescriptors:[NSArray arrayWithObject:[[NSSortDescriptor alloc] initWithKey:#"_pk" ascending:NO]]];
[fetchRequest setEntity:entity];
NSError* error;
NSString *uuid = uniqueId;
NSPredicate *pred = [NSPredicate predicateWithFormat:#"uuid = %#", uuid];
[fetchRequest setPredicate:pred];
// Query on managedObjectContext With Generated fetchRequest
NSArray *fetchedRecords = [self.managedObjectContext executeFetchRequest:fetchRequest error:&error];
// NSLog(#"fetchedRecords %#",fetchedRecords);
// Returning Fetched Records
return fetchedRecords;
I caught the stack trace for the above scenario
(
0 WEPA-PrintApp 0x000000010a235969 WEPA-PrintApp + 47465
1 CoreFoundation 0x00007fff9216acbc __CFNOTIFICATIONCENTER_IS_CALLING_OUT_TO_AN_OBSERVER__ + 12
2 CoreFoundation 0x00007fff9205c1b4 _CFXNotificationPost + 3140
3 Foundation 0x00007fff8c528ea1 -[NSNotificationCenter postNotificationName:object:userInfo:] + 66
4 AppKit 0x00007fff8f95725b -[NSApplication _postDidFinishNotification] + 291
5 AppKit 0x00007fff8f956fc6 -[NSApplication _sendFinishLaunchingNotification] + 191
6 AppKit 0x00007fff8f953dc6 -[NSApplication(NSAppleEventHandling) _handleAEOpenEvent:] + 574
7 AppKit 0x00007fff8f953805 -[NSApplication(NSAppleEventHandling) _handleCoreEvent:withReplyEvent:] + 244
8 Foundation 0x00007fff8c548458 -[NSAppleEventManager dispatchRawAppleEvent:withRawReply:handlerRefCon:] + 290
9 Foundation 0x00007fff8c5482c9 _NSAppleEventManagerGenericHandler + 102
10 AE 0x00007fff9047a99c _Z20aeDispatchAppleEventPK6AEDescPS_jPh + 531
11 AE 0x00007fff9047a719 _ZL25dispatchEventAndSendReplyPK6AEDescPS_ + 31
12 AE 0x00007fff9047a623 aeProcessAppleEvent + 295
13 HIToolbox 0x00007fff93e1b37e AEProcessAppleEvent + 56
14 AppKit 0x00007fff8f94fec6 _DPSNextEvent + 2665
15 AppKit 0x00007fff8f94efd0 -[NSApplication nextEventMatchingMask:untilDate:inMode:dequeue:] + 194
16 AppKit 0x00007fff8f942f73 -[NSApplication run] + 594
17 AppKit 0x00007fff8f92e424 NSApplicationMain + 1832
18 WEPA-PrintApp 0x000000010a250f96 WEPA-PrintApp + 159638
19 libdyld.dylib 0x00007fff917ae5c9 start + 1
)
This crash occurs not all the time. And uuid here is NSString. Can any one provide the solution to accomplish the issue?

Illegal attempt to establish a relationship when assigning object from child context

I spent few hours trying to solve problems with parent-child core data model. But let's start from the beginning. I've got main context and child context which has .parentContext as the main context.
- (NSManagedObjectContext *)mainContext {
if (!_mainContext) {
_mainContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[_mainContext setPersistentStoreCoordinator:self.persistentStoreCoordinator];
}
return _mainContext;
}
- (NSManagedObjectContext *)childContext {
if (!_childContext) {
_childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_childContext setParentContext:self.mainContext];
}
return _childContext;
}
Next I create two objects in separated contexts.
Entity2 *entity2 = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([Entity2 class])
inManagedObjectContext:_stack.childContext];
Entity1 *entity1 = [NSEntityDescription insertNewObjectForEntityForName:NSStringFromClass([Entity1 class])
inManagedObjectContext:_stack.mainContext];
entity1.arg1 = #"ABC";
entity1.arg2 = #"DEF";
Here all is ok.
Then I want to add one object to relationship of another, no matter if I try to add entity1 to entity2 or vice versa.
[entity1 setEntity2:entity2];
In article of Multi-Context Core Data | Cocoanetics I read that I should perform block with save operation because object's don't know each other. So it look like this:
[_stack.childContext performBlock:^{
NSError *error;
if (![_stack.childContext save:&error]) {
NSLog(#"Error: %#", error);
}
[_stack.mainContext performBlock:^{
NSError *error;
if (![_stack.mainContext save:&error]) {
NSLog(#"Error: %#", error);
}
[entity1 setEntity2:entity2];
}];
}];
But wherever I put [entity1 setEntity2:entity2] It ends with:
2014-06-22 08:48:24.444 MultiContextualCoreData[1324:60b] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Illegal attempt to establish a relationship 'entity1' between objects in different contexts (source = <Entity2: 0x8c81570> (entity: Entity2; id: 0x8c80000 <x-coredata:///Entity2/tC31696AE-0A0A-424E-9C8E-1E19085F3FB43> ; data: {
entity1 = nil;
}) , destination = <Entity1: 0x8c80200> (entity: Entity1; id: 0x8c80250 <x-coredata:///Entity1/tC31696AE-0A0A-424E-9C8E-1E19085F3FB42> ; data: {
arg1 = ABC;
arg2 = DEF;
entity2 = nil;
}))'
*** First throw call stack:
(
0 CoreFoundation 0x01b541e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x018d38e5 objc_exception_throw + 44
2 CoreData 0x00293b7e _PFManagedObject_coerceValueForKeyWithDescription + 3614
3 CoreData 0x002614e9 _sharedIMPL_setvfk_core + 185
4 CoreData 0x0027ada7 _svfk_0 + 39
5 MultiContextualCoreData 0x00002d4a -[AppDelegate test] + 554
6 MultiContextualCoreData 0x00002acd -[AppDelegate application:didFinishLaunchingWithOptions:] + 605
7 UIKit 0x0058d14f -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 309
8 UIKit 0x0058daa1 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1810
9 UIKit 0x00592667 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 824
10 UIKit 0x005a6f92 -[UIApplication handleEvent:withNewEvent:] + 3517
11 UIKit 0x005a7555 -[UIApplication sendEvent:] + 85
12 UIKit 0x00594250 _UIApplicationHandleEvent + 683
13 GraphicsServices 0x03a07f02 _PurpleEventCallback + 776
14 GraphicsServices 0x03a07a0d PurpleEventCallback + 46
15 CoreFoundation 0x01acfca5 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
16 CoreFoundation 0x01acf9db __CFRunLoopDoSource1 + 523
17 CoreFoundation 0x01afa68c __CFRunLoopRun + 2156
18 CoreFoundation 0x01af99d3 CFRunLoopRunSpecific + 467
19 CoreFoundation 0x01af97eb CFRunLoopRunInMode + 123
20 UIKit 0x00591d9c -[UIApplication _run] + 840
21 UIKit 0x00593f9b UIApplicationMain + 1225
22 MultiContextualCoreData 0x00002efd main + 141
23 libdyld.dylib 0x0219b701 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
What i did wrong here?
Thank you for help in advance.
The issue is that two objects have to belong to the same context in order to establish relationships between them. In your case, one of the contexts has a private type, it has its own queue to work at, where the main context works on the main queue. This is a way to protect you from running into concurrency problems down the road.
Possible solution are
Create the entity1, save the main context, retrieve it in the child context using managedObjectID or a fetch request if it makes more sense and only then establish relationship when you have entity1 and entity2 in the same context
Or, simply, create both objects in the same context, if your logic allows it.

iOS Core Data NSRangeException

I have an issue I cant solve. Im creating an iOS application with Core Data framework. Everything was going just fine until I got NSRangeException. This exception I get in function which checks if Application data needs to be updated.
My code is:
- (BOOL) isTimetableUpdatedWithJSONData:(NSMutableDictionary*) data
{
appDelegate = [[UIApplication sharedApplication] delegate];
managedObjectContext = [appDelegate managedObjectContext];
//Do database update check logic here
NSFetchRequest *request = [[NSFetchRequest alloc] init];
[request setEntity:[NSEntityDescription entityForName:#"MobileTimetableDataHash" inManagedObjectContext:managedObjectContext]];
NSError *error = nil;
NSArray *results = [managedObjectContext executeFetchRequest:request error:&error];
if (error != nil)
{
[self printErrorAlert];
}
//THERE IS ERROR HERE
NSManagedObject* changesGrabbed = [results objectAtIndex:0];
NSString *changesFromDatabase = [changesGrabbed valueForKey:#"changes"];
NSString *changesFromService = [data valueForKeyPath:#"changes"];
if ([changesFromService isEqualToString:changesFromDatabase])
{
return YES;
}
else
{
[changesGrabbed setValue:changesFromService forKey:#"changes"];
[managedObjectContext save:&error];
if (error != nil)
{
[self printErrorAlert];
}
return NO;
}
}
Exception:
2014-06-12 21:36:12.034 MIF[437:60b] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for empty array'
*** First throw call stack:
(
0 CoreFoundation 0x0000000101cb3495 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000101a1299e objc_exception_throw + 43
2 CoreFoundation 0x0000000101c6be3f -[__NSArrayI objectAtIndex:] + 175
3 MIF 0x0000000100001942 -[MIFTimetableService isTimetableUpdatedWithJSONData:] + 514
4 MIF 0x000000010000219d -[MIFAppDelegate synchrinizeTimetableService] + 157
5 MIF 0x0000000100001dc2 -[MIFAppDelegate application:didFinishLaunchingWithOptions:] + 114
6 UIKit 0x00000001005ba3d9 -[UIApplication _handleDelegateCallbacksWithOptions:isSuspended:restoreState:] + 264
7 UIKit 0x00000001005babe1 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1605
8 UIKit 0x00000001005bea0c -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 660
9 UIKit 0x00000001005cfd4c -[UIApplication handleEvent:withNewEvent:] + 3189
10 UIKit 0x00000001005d0216 -[UIApplication sendEvent:] + 79
11 UIKit 0x00000001005c0086 _UIApplicationHandleEvent + 578
12 GraphicsServices 0x0000000103ce671a _PurpleEventCallback + 762
13 GraphicsServices 0x0000000103ce61e1 PurpleEventCallback + 35
14 CoreFoundation 0x0000000101c35679 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 41
15 CoreFoundation 0x0000000101c3544e __CFRunLoopDoSource1 + 478
16 CoreFoundation 0x0000000101c5e903 __CFRunLoopRun + 1939
17 CoreFoundation 0x0000000101c5dd83 CFRunLoopRunSpecific + 467
18 UIKit 0x00000001005be2e1 -[UIApplication _run] + 609
19 UIKit 0x00000001005bfe33 UIApplicationMain + 1010
20 MIF 0x0000000100001d23 main + 115
21 libdyld.dylib 0x000000010234b5fd start + 1
22 ??? 0x0000000000000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
Guys, can anyone help me please? I realy need your help. Thank you.
Your troublemaker seems to be
NSManagedObject* changesGrabbed = [results objectAtIndex:0];
If results is an empty array, calling objectAtIndex:0 will cause a NSRangeException, because there is no object at index 0. You better call [results firstObject], which won't crash with an error if results is empty array. firstObject() just returns nil in this case.
You are attempting to retrieve an object from an empty array. You should first check to see if the array contains any objects. Use the count property:
if (results.count > 0) {
NSManagedObject* changesGrabbed = [results objectAtIndex:0];
//continue...
} else {
//Array is empty, object 0 will be beyond bounds
}
Just before
NSManagedObject* changesGrabbed = [results objectAtIndex:0];
Add a branch based on the returned results. Something like the following:
if (results && [results count] > 0) {
NSManagedObject* changesGrabbed = [results objectAtIndex:0];
...
}
Your array is empty. The stacktrace pretty much spells it out for you --
reason: '* -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for
empty array'

Core Data crash with Invalid predicate: nil RHS

I have this crash while executing a fetch request, but from the crash report it is clear that the cause for the crash is that the predicate is nil. I have added a check for the case the startDate is nil. Is there any other potential cause for the invalid predicate I should take care of?
NSFetchRequest *calRequest = [NSFetchRequest fetchRequestWithEntityName:#"Calendar"];
calRequest.predicate = [NSPredicate predicateWithFormat:#"date >= %#", startDate];
calRequest.sortDescriptors = #[[NSSortDescriptor sortDescriptorWithKey:#"date" ascending:YES]];
NSError *error = nil;
NSArray *results = [appDelegate.managedObjectContext executeFetchRequest:calRequest error:&error];
Crash report
Thread : Fatal Exception: NSInvalidArgumentException
0 CoreFoundation 0x30534f03 __exceptionPreprocess + 130
1 libobjc.A.dylib 0x3acc9ce7 objc_exception_throw + 38
2 CoreData 0x30289f17 -[NSComparisonPredicate(_NSCoreDataSQLPredicateCategories) minimalFormInContext:] + 926
3 CoreData 0x3028952b -[NSSQLGenerator initializeContextForFetchRequest:ignoreInheritance:nestingLevel:] + 538
4 CoreData 0x30288f9f -[NSSQLGenerator newSQLStatementForFetchRequest:ignoreInheritance:countOnly:nestingLevel:] + 34
5 CoreData 0x30288e3f -[NSSQLAdapter _newSelectStatementWithFetchRequest:ignoreInheritance:] + 406
6 CoreData 0x30288aa3 -[NSSQLCore newRowsForFetchPlan:] + 114
7 CoreData 0x302881e7 -[NSSQLCore objectsForFetchRequest:inContext:] + 698
8 CoreData 0x30287c8b -[NSSQLCore executeRequest:withContext:error:] + 446
9 CoreData 0x30287539 -[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 2892
10 CoreData 0x3028593b -[NSManagedObjectContext executeFetchRequest:error:] + 614
11 MyApp 0x0010b769 -[Calendar calendarLoad] (Calendar.m:152)
...

Resources