Как мы можем справиться с этим, когда блок в GCD не выполняется? - PullRequest
3 голосов
/ 25 ноября 2011

Я очень новичок в подходе GCD. Я пытаюсь синхронизировать данные из Интернета, используя блоки в GCD. У меня есть ситуация, когда если выполняется операция синхронизации и происходит сбой сети, то происходит сбой моего приложения. Когда блоки не используются, я могу справиться с этим с помощью метода @ try / @ catch. Но когда я пытаюсь сделать это с блоками и GCD, я не могу обработать сбой или исключение. Любые идеи о том, как справиться с аварией?

Вызов синхронизации аккаунтов в блоке:

dispatch_async(exampleQueue, ^{
    dispatch_async(dispatch_get_main_queue(), ^{
        [self sendSyncStatusUpdate:@"Loading Accounts"];
    });

    [AccountService syncAccounts];
    [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:@"accountsFirstSyncCompleted"];

    dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
    });
});

- Метод [AccountService syncAccounts]:

@try {
    ZKDescribeSObject *accountDescription = [app.client describeSObject:@"Account"];
    NSString *query = [NSString stringWithFormat:@"Select %@ From Account Where LastModifiedDate > %@", [accountDescription fieldsAsCsv], [dateTimeFormatter stringFromDate:lastSyncDate]];

    ZKQueryResult *result = [[app.client query:query batchSize:[NSNumber numberWithInt:200]] retain];
}
@catch (ZKSoapException *e) {
    [RootViewController hadSyncError:e];
}

Я не могу отловить исключение, которое возникает, когда мы отключаемся во время синхронизации.

1 Ответ

2 голосов
/ 19 января 2012

Это вполне выполнимо. Как предполагает комментатор, вы можете использовать @ try / @ catch в блоках без инцидентов. Используя ваш код, например:

dispatch_async(exampleQueue, ^{
    dispatch_async(dispatch_get_main_queue(), ^{
        [self sendSyncStatusUpdate:@"Loading Accounts"];
    });

    BOOL error = NO;    

    @try {
        // I pasted this code in line, but you could take the @try/@catch out of the
        // syncAccounts method, and just let the exception bubble up to here.
        ZKDescribeSObject *accountDescription = [app.client describeSObject:@"Account"];
        NSString *query = [NSString stringWithFormat:@"Select %@ From Account Where LastModifiedDate > %@", [accountDescription fieldsAsCsv], [dateTimeFormatter stringFromDate:lastSyncDate]];

        ZKQueryResult *result = [[app.client query:query batchSize:[NSNumber numberWithInt:200]] retain];
    }
    @catch (ZKSoapException *e) 
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            [RootViewController hadSyncError:e];
        });

        error = YES;
    }

    if (error)
    {
        dispatch_async(dispatch_get_main_queue(), ^{
            [self sendSyncStatusUpdate:@"Failed to Sync Accounts!"];
        });
        return;
    }

    [[NSUserDefaults standardUserDefaults] setObject:[NSNumber numberWithBool:YES] forKey:@"accountsFirstSyncCompleted"];

    dispatch_async(dispatch_get_main_queue(), ^{
        [self.tableView reloadData];
    });
});

Это прекрасный способ использования GCD.

...