Jeremy Smith
Jeremy Smith

Reputation: 15079

Problem with using dispatch_async, can't fire two function calls on the same controller?

I have the following method in my AppDelegate. I cannot find a way to to update the label on the updateView and perform the upload via ASIHTTPRequest. In the code below, it will perform the upload (startUpload), but not update the label (updateLabel). If I comment out the call to startUpload, it will update the label. I also tried creating a dispatch queue within uploadViewController, and that had a similar result where I could only get one of the two methods to work.

- (void) showProgressView:(NSString *)filePath {
    NSView *view = [uploadViewController view];
    dispatch_queue_t queue = dispatch_get_global_queue(0,0);
    dispatch_async(queue, ^{
        // assigns the upload view to the root NSPanel
        [box setContentView:view];
    });
    dispatch_async(queue, ^{
        // starts the upload using ASIHTTPRequest
        [uploadViewController startUpload:filePath];
    });
    dispatch_async(queue, ^{
        // updates a label in the upload view
        [uploadViewController updateLabel];
    });
}

In UploadViewController:

-(void)startUpload:(NSString *)filePath {
    HandZipper *handZipper = [HandZipper alloc];
    zipPath = [handZipper compressHands:(filePath):(processStatus)];   

    ASIFormDataRequest *request = [[[ASIFormDataRequest alloc] initWithURL:[NSURL URLWithString:@"http://allseeing-i.com/ignore"]] autorelease];

    [request setRequestMethod:@"PUT"];
    [request setPostBodyFilePath:zipPath];
    [request setShouldStreamPostDataFromDisk:YES];
    [request setDelegate:self];
    [request setUploadProgressDelegate:progressIndicator];
    [request setDidFinishSelector:@selector(postFinished:)];
    [request setDidFailSelector:@selector(postFailed:)];
    [request startSynchronous]; 

}

Upvotes: 0

Views: 749

Answers (1)

Joe
Joe

Reputation: 57179

You should always update UI elements on the main thread. If you know that showProgressView: will be called from the main thread then remove the dispatch_async from around [box setContentView:view]; and [uploadViewController updateLabel]; and just call them directly. Otherwise if showProgressView: might be called from another thread then just use dispatch_get_main_queue(void) instead of queue.

Upvotes: 2

Related Questions