IPhone:使用dispatch_async进行文件上传以进行后台上传

时间:2011-09-26 22:26:24

标签: iphone file asynchronous upload background

我想在后台运行应用程序时执行图片上传。我可以使用此链接上的代码将图像上传到服务器。 How can I upload a photo to a server with the iPhone?

我听说NSUrlConnection可以是异步的,它在EPUploader中使用。在我的代码中,我添加了一些额外的方法,它将在用于EPUploader的应用程序目录中创建一个文件。在创建文件的过程中,我不希望它在应用程序的主线程上创建,所以我将所有代码包括EPUploader本身与 全局队列上的dispatch_async。这样我就不会在文件创建时阻塞主线程。

如果我使用dispatch_sync但是dispatch_async没有问题我在NSUrlConnection连接处放置断点时发现了一些奇怪的东西:

- (void)upload

{

    NSData *data = [NSData dataWithContentsOfFile:filePath];
    //ASSERT(data);
    if (!data) {
            [self uploadSucceeded:NO];
        return;
    }
    if ([data length] == 0) {
        // There's no data, treat this the same as no file.
        [self uploadSucceeded:YES];
        return;
    } /* blah blah */
    NSURLConnection * connection = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];

     if (!connection) {
        [self uploadSucceeded:NO];
        return;
    }
    else
        return;

我在断点处调试,而不是转到if语句,调试器跳转到此方法的第一个return语句。之后,我传递给这个类的选择器永远不会被调用。这只发生在dispatch_async上,它适用于全局队列上的dispatch_sync。

有人知道如何解决这个问题吗?

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

dispatch_async(queue, ^{
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];     

    self.uploadIndex = 0;
    ALAsset *asset = [self.assets objectAtIndex:0];

    [[FileUploader alloc] initWithAsset:[NSURL URLWithString:@"http://192.168.0.3:4159/default.aspx"]
                                  asset:asset
                               delegate:self
                           doneSelector:@selector(onUploadDone:)
                          errorSelector:@selector(onUploadError:)];
    //[self singleUpload:self.uploadIndex];
    [pool release];


});

1 个答案:

答案 0 :(得分:1)

有几件事情应该改变。

  1. 删除NSAutoreleasePool,不需要。
  2. 将块复制到堆中,因为它的生命可能会超过调用代码的生命周期。
  3. 示例:

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
    
        dispatch_async(queue, [[^{
            self.uploadIndex = 0;
            ALAsset *asset = [self.assets objectAtIndex:0];
    
            [[FileUploader alloc] initWithAsset:[NSURL URLWithString:@"http://192.168.0.3:4159/default.aspx"]
                                          asset:asset
                                       delegate:self
                                   doneSelector:@selector(onUploadDone:)
                                  errorSelector:@selector(onUploadError:)];
        } copy] autorelease]);
    

    如果你正在使用ARC(你当然应该这样),则不需要copyautorelease