Van Du Tran
Van Du Tran

Reputation: 31

iphone ios thread issue: delegate object not responding when using dispatch_async

Here's my code:

MainDelegate.m

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {  
FetchManager *fetchManager = [FetchManager sharedInstance];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH,0), ^{
[fetchManager fetchData];
});

//regular code continues

}

FetchData.m(this is a singleton class)

- (id)getInstance { ... }

- (void)fetchData
{
    NSURL *url = [NSURL URLWithString:@"http://www.data.xml"];
    NSURLRequest *request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestReloadIgnoringCacheData timeoutInterval:30];

    if (connectionInProgress) {
        [connectionInProgress cancel];
        [connectionInProgress release];
    }

    [xmlData release];
    xmlData = [[NSMutableData alloc] init];

    connectionInProgress = [[NSURLConnection alloc] initWithRequest:request delegate:self startImmediately:YES];  
}

/*and all necessary NSXMLParserDelegate protocol methods are implemented - not shown here*/

Problem: none of the NSXMLParserDelegate protocol methods are fired. I do not know why. If I remove the "dispatch_async" in the didFinishLaunchingWithOptions method, then things are working as expected - the NSXMLParserDelegate protocol methods are fired.

Anyone see the problem?

Upvotes: 3

Views: 1112

Answers (2)

Andrea
Andrea

Reputation: 26383

As stated by Caleb NSURLConnection needs a run loop. One way to accomplish what you want is create a subclass of NSOperation that keeps the loop alive and that manages delegation callbacks. the other way around is use this amazing new Api that just need the creation of an NSOperationQueue, but is only available on iOS5 sendAsynchronousRequest:queue:completionHandler

Upvotes: 0

Caleb
Caleb

Reputation: 125007

Two things jump out:

  1. NSURLConnection requires a run loop to operate. When you run on the main thread, there's automatically a run loop that the connection will schedule itself on. When you use dispatch_async(), your block is scheduled in some secondary thread that may not have a run loop, or whose run loop may not be in a mode that allows NSURLConnection to operate.

  2. Even if the connection could schedule itself, the block ends right after the connection is created. NSURLConnection expects send its delegate messages on the thread where it was created, but how would that work if the block has ended? Is there some sort of valid context in which the delegate can be called on that thread?

Upvotes: 2

Related Questions