Search code examples
ioscore-datansfetchrequest

executeFetchRequest hangs and never returns error or proceeds


I'm using the AppDelegate's default managedObjectContext, and when I executeFetchRequest on it, it never goes to the next line or crashes with an error. This is on a background thread, so the UI does not freeze, but the data is never populated -- my activity indicator never stops and my debugging tell me it never gets off that statement. I stepped through each line, and I narrowed it down to the executeFetchRequest method. What might be causing this? There are no objects saved, but I don't think that should have anything to do with it. So far, it's been an hour, so something has gone wrong clearly. Lastly, this only happens like 40% of the time.

Here's what the code looks like:

NSSortDescriptor *byTimestamp = [NSSortDescriptorWithKey:@"timestamp" ascending:NO];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName:@"Message"];
[fetchRequest setSortDescriptors:@[byTimestamp]];
NSManagedObjectContext *managedObjectContext = [self managedObjectContext];
NSArray *messages = [managedObjectContext executeFetchRequest:fetchRequest error:&error];//hangs on this line!!
if(error != nil)
  NSLog(@"Error: %@", [error localizedDescription]);

Here's my backtrace:

* thread #1: tid = 0x1c03, 0x9329d7d2 libsystem_kernel.dylib`mach_msg_trap + 10, stop reason = signal SIGSTOP
    frame #0: 0x9329d7d2 libsystem_kernel.dylib`mach_msg_trap + 10
    frame #1: 0x9329ccb0 libsystem_kernel.dylib`mach_msg + 68
    frame #2: 0x02488a49 CoreFoundation`__CFRunLoopServiceMachPort + 185
    frame #3: 0x0248d84b CoreFoundation`__CFRunLoopRun + 1243
    frame #4: 0x0248cf44 CoreFoundation`CFRunLoopRunSpecific + 276
    frame #5: 0x0248ce1b CoreFoundation`CFRunLoopRunInMode + 123
    frame #6: 0x029637e3 GraphicsServices`GSEventRunModal + 88
    frame #7: 0x02963668 GraphicsServices`GSEventRun + 104
    frame #8: 0x0041165c UIKit`UIApplicationMain + 1211
    frame #9: 0x000027ad qub`main(argc=1, argv=0xbffff418) + 141 at main.m:16

  thread #3: tid = 0x2203, 0x932a09ca libsystem_kernel.dylib`kevent64 + 10
    frame #0: 0x932a09ca libsystem_kernel.dylib`kevent64 + 10
    frame #1: 0x01c8cc2b libdispatch.dylib`_dispatch_mgr_invoke + 863
    frame #2: 0x01c8c8cc libdispatch.dylib`_dispatch_mgr_thread + 61

  thread #4: tid = 0x2303, 0x932a00ee libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #0: 0x932a00ee libsystem_kernel.dylib`__workq_kernreturn + 10
    frame #1: 0x9017904c libsystem_c.dylib`_pthread_workq_return + 45
    frame #2: 0x90178e19 libsystem_c.dylib`_pthread_wqthread + 448

  thread #5: tid = 0x2403, 0x9329d7d2 libsystem_kernel.dylib`mach_msg_trap + 10
    frame #0: 0x9329d7d2 libsystem_kernel.dylib`mach_msg_trap + 10
    frame #1: 0x9329ccb0 libsystem_kernel.dylib`mach_msg + 68
    frame #2: 0x02488a49 CoreFoundation`__CFRunLoopServiceMachPort + 185
    frame #3: 0x0248d8d4 CoreFoundation`__CFRunLoopRun + 1380
    frame #4: 0x0248cf44 CoreFoundation`CFRunLoopRunSpecific + 276
    frame #5: 0x0248ce1b CoreFoundation`CFRunLoopRunInMode + 123
    frame #6: 0x055ad310 WebCore`RunWebThread(void*) + 608
    frame #7: 0x90176557 libsystem_c.dylib`_pthread_start + 344

  thread #8: tid = 0x2703, 0x9329d7d2 libsystem_kernel.dylib`mach_msg_trap + 10
    frame #0: 0x9329d7d2 libsystem_kernel.dylib`mach_msg_trap + 10
    frame #1: 0x9329ccb0 libsystem_kernel.dylib`mach_msg + 68
    frame #2: 0x02488a49 CoreFoundation`__CFRunLoopServiceMachPort + 185
    frame #3: 0x0248d8d4 CoreFoundation`__CFRunLoopRun + 1380
    frame #4: 0x0248cf44 CoreFoundation`CFRunLoopRunSpecific + 276
    frame #5: 0x0248ce1b CoreFoundation`CFRunLoopRunInMode + 123
    frame #6: 0x00ec7c7c Foundation`-[NSRunLoop(NSRunLoop) runMode:beforeDate:] + 298
    frame #7: 0x00ec7b45 Foundation`-[NSRunLoop(NSRunLoop) run] + 82
    frame #8: 0x00085c60 qub`+[AFURLConnectionOperation networkRequestThreadEntryPoint:](self=0x000d2f1c, _cmd=0x000af418, object=0x00000000) + 304 at AFURLConnectionOperation.m:195
    frame #9: 0x00f150d5 Foundation`-[NSThread main] + 76
    frame #10: 0x00f15034 Foundation`__NSThread__main__ + 1304
    frame #11: 0x90176557 libsystem_c.dylib`_pthread_start + 344

  thread #9: tid = 0x2803, 0x9329d7d2 libsystem_kernel.dylib`mach_msg_trap + 10
    frame #0: 0x9329d7d2 libsystem_kernel.dylib`mach_msg_trap + 10
    frame #1: 0x9329ccb0 libsystem_kernel.dylib`mach_msg + 68
    frame #2: 0x02488a49 CoreFoundation`__CFRunLoopServiceMachPort + 185
    frame #3: 0x0248d8d4 CoreFoundation`__CFRunLoopRun + 1380
    frame #4: 0x0248cf44 CoreFoundation`CFRunLoopRunSpecific + 276
    frame #5: 0x0248ce1b CoreFoundation`CFRunLoopRunInMode + 123
    frame #6: 0x00fccebe Foundation`+[NSURLConnection(Loader) _resourceLoadLoop:] + 393
    frame #7: 0x00f150d5 Foundation`-[NSThread main] + 76
    frame #8: 0x00f15034 Foundation`__NSThread__main__ + 1304
    frame #9: 0x90176557 libsystem_c.dylib`_pthread_start + 344

  thread #10: tid = 0x2903, 0x9329fbe6 libsystem_kernel.dylib`select$DARWIN_EXTSN + 10
    frame #0: 0x9329fbe6 libsystem_kernel.dylib`select$DARWIN_EXTSN + 10
    frame #1: 0x024cacb7 CoreFoundation`__CFSocketManager + 1255
    frame #2: 0x90176557 libsystem_c.dylib`_pthread_start + 344

  thread #11: tid = 0x2a03, 0x9329f91a libsystem_kernel.dylib`__psynch_mutexwait + 10
    frame #0: 0x9329f91a libsystem_kernel.dylib`__psynch_mutexwait + 10
    frame #1: 0x9017c13b libsystem_c.dylib`pthread_mutex_lock + 595
    frame #2: 0x014cdb01 CoreData`-[_PFLock lock] + 33
    frame #3: 0x014cdada CoreData`-[NSPersistentStoreCoordinator lock] + 42
    frame #4: 0x014e257e CoreData`-[NSPersistentStoreCoordinator executeRequest:withContext:error:] + 1182
    frame #5: 0x014e09c9 CoreData`-[NSManagedObjectContext executeFetchRequest:error:] + 569
    frame #6: 0x000492fe qub`__36-[RIPConvosViewController pullData:]_block_invoke(.block_descriptor=0x118e9320, newMessages=0x00000000, oldMessages=0x00000000) + 638 at RIPConvosViewController.m:73
    frame #7: 0x00048fb4 qub`-[RIPConvosViewController pullData:](self=0x075293d0, _cmd=0x000abda7, completion=0xb0375ef0) + 212 at RIPConvosViewController.m:103
    frame #8: 0x0004bab8 qub`__40-[RIPConvosViewController refreshTable:]_block_invoke(.block_descriptor=0x118d2e50) + 168 at RIPConvosViewController.m:236
    frame #9: 0x01c8753f libdispatch.dylib`_dispatch_call_block_and_release + 15
    frame #10: 0x01c99014 libdispatch.dylib`_dispatch_client_callout + 14
    frame #11: 0x01c8a2e8 libdispatch.dylib`_dispatch_root_queue_drain + 335
    frame #12: 0x01c8a450 libdispatch.dylib`_dispatch_worker_thread2 + 39
    frame #13: 0x90178e12 libsystem_c.dylib`_pthread_wqthread + 441

By the way, this code is in a block called fetchBlock in the pullData method in the RIPConvosViewController class.

I believe this is a threading problem, but I do not know how to solve this -- should I make sure all my calls to Core Data are on the same thread?? How do I do this if this is the solution?


Solution

  • I had the same problem and checked this thread : executeFetchRequest:error: freezes app

    I solved it by putting my NSManagedObjectContext requests in a @synchronized block.

    My code was :

    -(void)saveBookmarksToCache:(NSMutableArray *) bookmarkList error:(NSError **)error
    {
    
        NSFetchRequest *allBookmarks = [[NSFetchRequest alloc] init];
        [allBookmarks setEntity:self.bookmarkDescription];
        [allBookmarks setIncludesPropertyValues:NO]; // Just fetch the Id
    
        __autoreleasing NSError *reqError = nil;
        NSArray *bookmarks = [self.managedObjectContext executeFetchRequest:allBookmarks error:&reqError];
    
    
        if (reqError != nil)
            error = &reqError;
        ...
    
        // Save
        [self.managedObjectContext save:&reqError];
        ...
    }
    

    and it kept hanging on the executeFetchRequest line (I have several classes that perform the same kind of process, at more or less the same time).

    As advised in the other thread, I transformed it into :

    -(void)saveBookmarksToCache:(NSMutableArray *) bookmarkList error:(NSError **)error
    {
    
        NSFetchRequest *allBookmarks = [[NSFetchRequest alloc] init];
        [allBookmarks setEntity:self.bookmarkDescription];
        [allBookmarks setIncludesPropertyValues:NO]; // Just fetch the Id
    
        __autoreleasing NSError *reqError = nil;
        // Lock the PersistenStoreCoordinator for the whole process
        @synchronized(self.persistentStoreCoordinator) {
            NSArray *bookmarks = [self.managedObjectContext executeFetchRequest:allBookmarks error:&reqError];
    
            if (reqError != nil)
                error = &reqError;
            ...
    
            // Save
            [self.managedObjectContext save:&reqError];
            ...
    
        }
    }
    

    It seems to have solved the problem for me.