iOS中的dispatch_async和block

33

这段代码是什么意思?

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        TMBaseParser *parser=[[TMBaseParser alloc] init];
        parser.delegate=self;
        NSString *post =nil;
        NSData *postData = [post dataUsingEncoding:NSUTF8StringEncoding];
        [parser parseForServiceType:TMServiceCategories postdata:postData];
    });

请简要解释。


那段代码看起来很奇怪:首先将 post 设置为 nil。在下一行发送了一个消息给 post。这样做没有任何作用,对吧? - Maarten
如果post == nil,那么[post dataUsingEncoding:NSUTF8StringEncoding]也会返回nil。 - ahwulf
3个回答

105

在这段代码中

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

});

为了避免解析数据这一耗时任务阻塞主线程,该过程在后台线程上异步运行。这样做是因为如果阻塞了主线程,将会停止所有动画,应用程序也会失去响应。

如果你想了解更多信息,请阅读苹果公司关于Grand Central DispatchDispatch Queue的文档。


7
如果上述代码片段无法正常运行,请尝试以下方法: Objective-C:
dispatch_async(dispatch_get_main_queue(), ^{

});

UI更新应始终从主队列执行。 "^"符号表示块的开始。

Swift 3:

DispatchQueue.global(qos: .background).async {
    print("This is run on the background queue")

    DispatchQueue.main.async {
        print("This is run on the main queue, after the previous code in outer block")
    }
}

, ^这两个符号有什么作用?这个例子适用于哪个 swift 版本? - Sentry.co
@GitSyncApp,我已经更新了我的答案。请检查一下... :) - Md Rais
2
只是需要澄清一下:"有时候即使后台线程想要更新UI,也无法这样做,因此你必须强制主线程将代码执行到主队列中",这是不正确的。UI更新必须始终在主线程上执行,这是绝对不能选用其他方式的。 - Miguel Rojas Cortés
1
完全正确,@MiguelRojasCortés。我已经更新了我的答案。 - Md Rais

2

这是一个Grand Central Dispatch块。

  1. dispatch_async是在另一个队列上运行的调用。
  2. dispatch_get_global_queue是获取具有所需特性的特定队列的调用。例如,代码可以在DISPATCH_QUEUE_PRIORITY_BACKGORUND上以低优先级运行。
  3. 在块内部,代码什么也不做。Post设置为nil。然后向nil发送了一条消息"dataUsingEncoding"。Objective C会忽略所有对nil的调用。最后,将“nil”postData发送给解析器。
  4. 在最好的情况下,这将什么也不做。在最坏的情况下,向解析器发送nil数据将导致崩溃。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接