如何使用NSURLConnection异步上传大图像?

时间:2011-05-13 17:27:21

标签: iphone ios facebook nsurlconnection grand-central-dispatch

现在,我正在尝试使用FBConnect将照片图片上传到Facebook。 我成功地从主线程上传图像,但它阻止用户界面很长时间。

所以,我尝试使用dispatch_async来解决阻塞问题。通过使用调度队列,可以解决UI阻止问题,但照片数据上传不再起作用。

NSMutableDictionary *params = [NSMutableDictionary dictionaryWithObjectsAndKeys:
                               img, @"picture",
                               nil];
dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

[params retain];
dispatch_async(aQueue, ^{        
    [facebook requestWithMethodName:@"photos.upload"
                          andParams:params
                      andHttpMethod:@"POST"
                        andDelegate:self];
    [params release];
    dispatch_async(aQueue, ^{ [uploadingIndicator stopAnimating]; });
});

我认为这个问题与NSURLConnection有关。 FBConnect使用NSURLConnection将图像数据发布到Facebook。如果我从调度队列调用FBConnect API,调度队列线程中调用的NSURLConnection方法可能没有运行循环。

_connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

我尝试使用scheduleInRunLoop。但是,没用。

_connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
[_connection scheduleInRunLoop:[NSRunLoop mainRunLoop] forMode:NSDefaultRunLoopMode];

如何解决此问题?有什么建议吗?

BR, Wonil。

1 个答案:

答案 0 :(得分:1)

问题可能是你在后台线程中运行了几个UIKit方法。与UIKit的所有交互必须在主线程中完成,主线程处理所有用户输入。

我不熟悉您正在使用的Facebook API方法,但似乎它正在使用UIImage。如果您可以使用支持CGImage,或者使用不与任何UIKit对象交互的其他方法,则可以解决该问题。 (同样,我无法帮助你,因为我没有使用任何Facebook API。)此外,你需要从主线程中调用UIActivityIndicatorView方法stopAnimating

你可以设置这样的队列:

dispatch_queue_t myQueue = dispatch_queue_create("anyName", NULL);

dispatch_async(myQueue, ^{   
    // upload image to Facebook, but without using UIKit methods

    dispatch_async(dispatch_get_main_queue(), ^{ 
        [uploadingIndicator stopAnimating]; 
    });
});
dispatch_release(myQueue);

这样,您可以在后台线程中完成繁重的工作并返回主线程来调用任何UIKit方法。

更正:UIImage,以及UIColor和UIFont,都是UIKit对象的例外,它们可以安全地在主线程之外进行交互。 UIKit的其余大部分都不是线程安全的,当然包括UIImageView。 (我倾向于在深夜混淆UIImage和UIImageView。)