2011-07-18 79 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