Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS start Background Thread

I have a small sqlitedb in my iOS device. When a user presses a button, I fetch the data from sqlite & show it to user.

This fetching part I want to do it in a background thread (to not block the UI main thread). I do this like so -

[self performSelectorInBackground:@selector(getResultSetFromDB:) withObject:docids];

After the fetching & a little bit of processing, I need to update the UI. But since (as a good practice) we should not perform UI updation from background threads. I call a selector on mainthread like so -

[self performSelectorOnMainThread:@selector(showResults) withObject:nil waitUntilDone:NO];

But my App crashes in the first step. i.e. starting a background thread. Is this not a way to start background threads in iOS?

UPDATE 1: After [self performSelectorInBackground.... I get this stacktrace, no info what so ever -

enter image description here

UPDATE 2: I even tried, starting a background thread like so - [NSThread detachNewThreadSelector:@selector(getResultSetFromDB:) toTarget:self withObject:docids]; but still I get same stacktrace.

Just so that I clarify, when I perform this operation on main thread everything runs smooth...

UPDATE 3 This is the method I am trying to run from background

- (void)getResultSetFromDB:(NSMutableArray *)toProceessDocids {     SpotMain *mirror = [[SpotMain alloc] init];     NSMutableArray *filteredDocids = toProceessDocids;      if(![gMediaBucket isEqualToString:@""])         filteredDocids = [mirror FetchDocIdsForMediaBucketWithDocID:filteredDocids mBucket:gMediaBucket numRes:-1];     if(![gMediaType isEqualToString:@""])         filteredDocids = [mirror FetchDocIdsForMediaType:filteredDocids mediaType:gMediaType numRes:-1];     if(![gPlatform isEqualToString:@""])         filteredDocids = [mirror FetchDocIdsForPlatformID:filteredDocids platformId:@"1" numRes:-1];      self.resultSet = [mirror FetchObjectFromDocid:filteredDocids];     [filteredDocids release];     [mirror release];      [self performSelectorOnMainThread:@selector(showResults) withObject:nil waitUntilDone:NO];     return; } 
like image 962
Srikar Appalaraju Avatar asked Aug 14 '11 06:08

Srikar Appalaraju


People also ask

How do I run a background thread?

To specify the thread on which to run the action, construct the Handler using a Looper for the thread. A Looper is an object that runs the message loop for an associated thread. Once you've created a Handler , you can then use the post(Runnable) method to run a block of code in the corresponding thread.

What is main thread in IOS?

The main thread is the one that starts our program, and it's also the one where all our UI work must happen. However, there is also a main queue, and although sometimes we use the terms “main thread” and “main queue” interchangeably, they aren't quite the same thing.

What is background and foreground thread?

Background threads are identical to foreground threads with one exception: a background thread does not keep the managed execution environment running. Once all foreground threads have been stopped in a managed process (where the .exe file is a managed assembly), the system stops all background threads and shuts down.


2 Answers

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.

like image 82
Scott Forbes Avatar answered Oct 03 '22 20:10

Scott Forbes


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

like image 30
Pawan Ahire Avatar answered Oct 03 '22 20:10

Pawan Ahire