Как отслеживать объекты NSError в потоках? - PullRequest
0 голосов
/ 18 июля 2011

У меня есть набор асинхронных вызовов, порождаемых с использованием NSInvocationOperation:

- (void)listRequestQueue:(StoreDataListRequest *)request {
    [openListRequests addObject:request];

    NSInvocationOperation *requestOp = [[NSInvocationOperation alloc]
                                        initWithTarget:self
                                        selector:@selector(listRequestStart:)
                                        object:request];
    [opQueue addOperation:requestOp];
    [requestOp release];
}

- (void)listRequestStart:(StoreDataListRequest *)request {
    if(self.resourceData == nil) {
        //TODO fail appropriately...
        return;
    }

    StoreDataListResponse *response = [self newListResponseForProductID:request.productID];

    [self performSelectorOnMainThread:@selector(listRequestFinish:)
                           withObject:response waitUntilDone:NO];
    [response release];

    [self performSelectorOnMainThread:@selector(cleanUpListRequest:)
                           withObject:request waitUntilDone:NO];
}

- (void)listRequestFinish:(StoreDataListResponse *)response {
    [self.delegate storeData:self didReceiveListResponse:response];
}

- (StoreDataListResponse *)newListResponseForProductID:(NSString *)productID {
    CollectionData *data = [self.resourceData dataForProduct:productID];
    if(data == nil) {
        //TODO do something
    }

    StoreDataListResponse *response = [[StoreDataListResponse alloc] init];
    response.productID = productID;
    if(productID != data.productID) {
        //TODO fail; remove product from list
    }
    response.name = NSLocalizedString(@"Loading...", @"Loading message");
    response.blurb = NSLocalizedString(@"Waiting for response from server", @"Waiting for website to respond");
    return response;
}

Для каждого из TODO s в приведенном выше коде я должен решить проблему и сообщить всем обработчикамвещи потерпели неудачу и почему.Глядя на класс и документацию NSError, кажется, что это правильный ответ, но мне трудно понять, как начать работать с NSInvocationOperation и performSelectorOnMainThread:withObject:waitUntilDone:.Я, конечно, могу получить NSError s из newListResponseForProductID: метода, изменив его на что-то вроде этого:

- (StoreDataListResponse *)newListResponseForProductID:(NSString *)productID error:(NSError **)error;

Как мне вернуть сгенерированную ошибку в основной поток, чтобы я мог справиться снеудавшийся запрос?

1 Ответ

0 голосов
/ 18 июля 2011

Самый простой способ запустить любой код в главном потоке - это использовать GCD и блоки на iOS 4 и выше.Например:

dispatch_async(dispatch_get_main_queue(), ^(void) {
    // Your code to run on the main thread here, 
    // any variables in scope like NSError is captured.
});

Или используйте dispatch_sync(), если вы знаете, что находитесь в фоновом потоке и хотите завершить блок в основном потоке, прежде чем продолжить.

...