Solution 1:

If you use performSelectorInBackground:withObject: to spawn a new thread, then the performed selector is responsible for setting up the new thread's autorelease pool, run loop and other configuration details – see "Using NSObject to Spawn a Thread" in Apple's Threading Programming Guide.

You'd probably be better off using Grand Central Dispatch, though:

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    [self getResultSetFromDB:docids];
});

GCD is a newer technology, and is more efficient in terms of memory overhead and lines of code.


Updated with a hat tip to Chris Nolet, who suggested a change that makes the above code simpler and keeps up with Apple's latest GCD code examples.

Solution 2:

Well that's pretty easy actually with GCD. A typical workflow would be something like this:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0ul);
    dispatch_async(queue, ^{
        // Perform async operation
        // Call your method/function here
        // Example:
        // NSString *result = [anObject calculateSomething];
                dispatch_sync(dispatch_get_main_queue(), ^{
                    // Update UI
                    // Example:
                    // self.myLabel.text = result;
                });
    });

For more on GCD you can take a look into Apple's documentation here

Solution 3:

Enable NSZombieEnabled to know which object is being released and then accessed. Then check if the getResultSetFromDB: has anything to do with that. Also check if docids has anything inside and if it is being retained.

This way you can be sure there is nothing wrong.

Solution 4:

The default sqlite library that comes with iOS is not compiled using the SQLITE_THREADSAFE macro on. This could be a reason why your code crashes.

Solution 5:

Swift 2.x answer:

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)) {
        self.getResultSetFromDB(docids)
    }