Using multithreading: What could be causing this code to NOT allow re-entry into springboard? on newest questions tagged multithreading – Stack Overflow
I have an app which uploads images to a bunch of places at once, kinda like Instagram style.
It is setup with an NSOperationQueue that runs a bunch of NSOperation wrappers around an an asynchronous NSURLConnection.
Most questions that begin like this end in “the callbacks don’t get called because the calling thread is joined before they return. This is not that kind of question. I am getting my callbacks as expected, but I am also somehow preventing the app from backgrounding when the home button is pressed. I always thought this was not able to be blocked at all due to sandboxing, but somehow I have done it. Pressing the home button while the operations are running will do nothing until they are complete, at which point (20-30sec later) the app properly backgrounds.
*NB This seems to only happen on single core processor devices. I can reproduce only on my iPhone 4, but not my 4S or iPad 3.
Still interested? Here is my setup:
self.uploadQueue = [[NSOperationQueue alloc] init];
[self.uploadQueue setMaxConcurrentOperationCount:1];
[self.uploadQueue setSuspended:YES];
Later on, I add operations to the queue and then unsuspend it to start. Here is some code from those NSOperation subclasses:
- (BOOL)isConcurrent { return YES; }
- (BOOL)isExecuting { return self.executing; }
- (BOOL)isFinished { return self.finished; }
- (void)start {
// Omitted: check for cancel...
// Omitted: check if setup to run
[self willChangeValueForKey:@"isExecuting"];
self.executing = YES;
[self didChangeValueForKey:@"isExecuting"];
[self.sharer share];
CFRunLoopRun();
}
- (void)completeOperation {
[self willChangeValueForKey:@"isFinished"];
[self willChangeValueForKey:@"isExecuting"];
self.executing = NO;
self.finished = YES;
[self didChangeValueForKey:@"isExecuting"];
[self didChangeValueForKey:@"isFinished"];
CFRunLoopStop(CFRunLoopGetCurrent());
}
The share method sets up an asynchronous NSURLConnection and fires it off like so:
- (void)share {
// Omitted: connection setup
[NSURLConnection sendAsynchronousRequest:postRequest queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *responseData, NSError *error){
// handle error or success, then call
[self.currentOperation completeOperation];
}];
Aside from the side-effect I am trying to solve for, the code works in that it does what it is supposed to, the callbacks get called, the threads stay alive as long as they need to, and the operation queue only runs the specified number of operations at a time.
What have I tried? I tried:
- Calling the NSURLConnection on the
[NSOperationQueue currentQueue]. This caused the async connection to not callback the block. - Forcing each NSOperation onto the main thread in the
startmethod. This did not solve the problem, also caused code to sometime not work and the UI to sometimes freeze. - Implementing my own queue with a mutable array and GCD to get on the right dispatch thread. Couldn’t get it to work.
- Synchronous NSURLConnections in the operations. I didn’t really try this because it is not an option for me. Some of the network frameworks such as the Facebook iOS SDK do not have a synchronous option.
Pausing execution during the time after the home-button press, but before the operations are done yields nothing interesting. There doesn’t seem to be anything on the main thread waiting for a lock or execution to finish.


Am I setting this up like a complete bozo? What is going on here and how can I fix it?
source: http://stackoverflow.com/questions/11254236/what-could-be-causing-this-code-to-not-allow-re-entry-into-springboard
Using multithreading: using-multithreading
Recent Comments