【问题标题】:IPhone: File Upload using dispatch_async for background uploadiPhone:使用 dispatch_async 进行后台上传的文件上传
【发布时间】:2011-09-26 22:26:24
【问题描述】:

我想在后台运行应用程序时执行图像上传。我可以使用此链接上的代码将图像上传到服务器。 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];


});

【问题讨论】:

  • 很抱歉这么晚才添加块内容......

标签: iphone file asynchronous upload background


【解决方案1】:

有几件事需要改变。

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

例子:

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

【讨论】:

  • 感谢您的回复...我已经尝试过,但是当我设置断点时它给出了相同的结果。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2012-03-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-12
  • 1970-01-01
  • 2014-12-26
相关资源
最近更新 更多