如何跨线程跟踪 NSError 对象?

Posted

技术标签:

【中文标题】如何跨线程跟踪 NSError 对象?【英文标题】:How do I track NSError objects across threads? 【发布时间】:2011-07-18 15:28:50 【问题描述】:

我有一组使用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;

对于上述代码中的每个TODOs,我应该解决问题并让任何处理程序知道事情已经失败以及原因。查看NSError 类和文档,它似乎是合适的答案,但我无法弄清楚如何使用NSInvocationOperationperformSelectorOnMainThread:withObject:waitUntilDone:。我当然可以通过将NSErrors 从newListResponseForProductID: 方法中更改为以下内容:

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

如何将生成的错误返回到主线程,以便处理失败的请求?

【问题讨论】:

【参考方案1】:

在主线程上运行任何代码的最简单方法是在 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()

【讨论】:

使用dispatch_sync() 是使您的应用程序死锁的好方法;例如,如果主队列有 dispatch_sync()d 到您的后台队列。

以上是关于如何跨线程跟踪 NSError 对象?的主要内容,如果未能解决你的问题,请参考以下文章

跨线程操作Treeview

qt如何让控件在单独线程运行

Qt5跨线程信号和槽

通过 Qt 信号/槽跨线程传递对象

WPF怎么跨线程访问UI控件

c#中如何跨线程调用windows控件