2011-07-18 77 views
0

我使用NSInvocationOperation正在催生了一套異步調用的:如何跨線程跟蹤NSError對象?

- (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 IN上面的代碼中,我應該可以解決這個問題,讓任何處理程序知道事情已經失敗,這是爲什麼。查看NSError類和文檔,這似乎是一個合適的答案,但我無法弄清楚如何使用NSInvocationOperationperformSelectorOnMainThread:withObject:waitUntilDone:

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

如何得到錯誤產生回主線程,所以我可以對付失敗的請求:我可以將其更改爲這樣的事情肯定讓0​​出去了的newListResponseForProductID:方法嗎?

回答

0

在主線程上運行任何代碼的最簡單方法是在iOS 4及更高版本上使用GCD和塊。就像這樣:

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()如果你知道你是在後臺線程,想繼續之前的程序,完成主線程上。

+3

使用'dispatch_sync()'是鎖定應用程序的好方法;例如,如果主隊列具有'dispatch_sync()'d到您的背景隊列。 – bbum