IPhone: загрузка файлов с использованием dispatch_async для фоновой загрузки - PullRequest
0 голосов
/ 27 сентября 2011

Я хочу выполнить загрузку изображения при запущенном приложении в фоновом режиме.Я могу загрузить изображение на сервер, используя код по этой ссылке. Как я могу загрузить фотографию на сервер с 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 отладчик переходит к первому оператору возврата этого метода.После этого селекторы, которые я передал этому классу, никогда не вызывают.Это происходит только для 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 Ответ

1 голос
/ 27 сентября 2011

Есть пара вещей, которые следует изменить.

  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 (которым вы, безусловно, являетесь, поскольку вы должны быть), нет необходимости в copy или autorelease.

...