我怎么知道我是否在UI线程上执行某些操作?

时间:2012-11-16 03:46:29

标签: objective-c multithreading thread-safety

我写了一个测试来使用块来试验RestKit。我认为RKRequest.onDidLoadResponse需要包含一个dispatch_async()调用才能在主UI线程上获得响应,但令我惊讶的是,这导致了运行时异常,所以我把它拿出去了可以很好地更新界面。

我的问题代码如下:

- (IBAction)loadSeasons:(UIButton *)sender {
    [[RKClient sharedClient] get:@"/api/v1/seasons" usingBlock:^(RKRequest* req) {
        req.onDidLoadResponse = ^(RKResponse* res) {
            NSLog(@"Request Performed: %@", res.bodyAsString);
            self.textResponse.text = res.bodyAsString;
            //dispatch_async(dispatch_get_main_queue(), ^{
            //    NSLog(@"In main queue: %@", res.bodyAsString);
            //});
        };
    }];
}

如果我取消注释dispatch_async块,我会得到异常。那么我怎么知道何时需要使用它以及何时不需要?我应该测试一些告诉我正在执行的代码是否在主线程上的东西吗?

我是Objective-C的新手,这对我来说是早期的,所以我为可能是一个新手问题而道歉。

更新:取消注释以上代码时,会发生以下情况:

  1. 控制台以蓝色输出文本(lldb),未提供其他信息。
  2. 休息libobjc.A.dylib objc_msgSend:is shown in the editor on 0x1c2009b:movl 8(%edx),%edi with the message in green:线程1:EXC_BAD_ACCESS(代码= 1,地址= 0x40000008)`。< / LI>

1 个答案:

答案 0 :(得分:3)

要回答您的问题,您可以致电[NSThread isMainThread]查看当前主题。但是,您不需要为您的问题执行此操作,事实上,如果您已经在主线程中运行,则将执行块分派给主线程是完全合法的。

崩溃是因为执行块时存储变量的方式。当第一个块完成时,变量使用的堆栈内存可以被覆盖,所以当你的异步NSLog语句在第二个块中运行时,你的变量res已被破坏,所以它指向垃圾在你的日志语句中使用时会触发崩溃。

为了完整性,研究__block变量声明。要使res在您的第二个调度块中可引用,我相信您必须将其声明为__block变量,以通过在第一个块中声明它来将其移动到堆:__block RKResponse* response = res;然后在您的调度日志语句中使用response