In my app I am constantly doing Core Data work in the background.
Testflight has been reporting a lot of crashes on a specific fetch which gets the current logged in environment object from Core Data (I cannot replicate):
- (Environment *)getActiveEnvironment
{
AppDelegate *ad = [AppDelegate sharedAppDelegate];
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
[context setParentContext:ad.managedObjectContext];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Environment" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSError *error;
//crash points to this line
NSArray *items = [context executeFetchRequest:fetchRequest error:&error];
Environment *tempE = nil;
if(items.count > 0)
{
for(Environment *e in items)
{
if(!e.token && !e.url)
{
break;
}
Environment *mainContextTv = (Environment *)[ad.managedObjectContext objectWithID:e.objectID];
if(e.activeValue)
tempE = mainContextTv;
}
}
return tempE;
}
Here is the crash stack I am receiving from Testflight:
0 Tower-iSales-Tab 0x002b37b2 testflight_backtrace
1 Tower-iSales-Tab 0x002b2e4a TFSignalHandler
2 libsystem_platform.dylib 0x39144722 _sigtramp
3 CoreData 0x2e1b8cec _perform
4 CoreData 0x2e1c30f4 -[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]
5 CoreData 0x2e13477a -[NSManagedObjectContext executeFetchRequest:error:]
6 Tower-iSales-Tab 0x000c7082 -[MySingleton getActiveEnvironment] in MySingleton.m on Line 379
7 Tower-iSales-Tab 0x000c73f8 -[MySingleton getToken] in MySingleton.m on Line 416
8 Tower-iSales-Tab 0x0020c476 -[NetworkManager getPathForViewName:useTimeStamp:timeStamp:index:counter:] in NetworkManager.m on Line 699
9 Tower-iSales-Tab 0x0020aa5a __70-[NetworkManager checkForDataFilesShouldEmptyQueue:isInitialDownload:]_block_invoke167 in NetworkManager.m on Line 415
10 libdispatch.dylib 0x3901b8fa _dispatch_barrier_sync_f_invoke
11 Tower-iSales-Tab 0x0020a33e __70-[NetworkManager checkForDataFilesShouldEmptyQueue:isInitialDownload:]_block_invoke113 in NetworkManager.m on Line 335
12 libdispatch.dylib 0x39017102 _dispatch_call_block_and_release
13 libdispatch.dylib 0x3901c7e4 _dispatch_root_queue_drain
14 libdispatch.dylib 0x3901c9d0 _dispatch_worker_thread2
15 libsystem_pthread.dylib 0x39146dfe _pthread_wqthread
16 libsystem_pthread.dylib 0x39146cc3 start_wqthread
I read this answer which suggests to set the queue type to NSPrivateQueueConcurrencyType
, not NSConfinementConcurrencyType
which I can do, but this is not a crash I can replicate easily so i'd like to know for sure that would cause this crash.
That answer also suggest using the performBlockAndWait
block for background fetches, but in my function how would I? I need to return an Environment
object, I use this function all over my app.
Thanks
From what I understand, you don't have to use NSConfinementConcurrencyType
context here, as you're calling -getActiveEnvironment
only from the main thread. So you can do all operations on the main context (ad.managedObjectContext
).
The returned object should then be accessed only from the main thread. If you want to access it from some other thread you have to use objectWithID:
to get it in the context associated with that thread.