GCD块中的runLoop如何在没有源码的情况下工作

问题描述 投票:0回答:1

我试图了解 iOS 中的多线程编程。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
               , ^{
                    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL   URLWithString:@"http://www.google.com"]];
                    NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];

                    if (connection == nil) {
                        NSLog(@"Request failed");

                    } else {
                        NSLog(@"Request sent");
                    }
                    [[NSRunLoop currentRunLoop] run];//How does this work?
                   });

这段代码工作正常,我得到了预期的回调。

在文档中https://developer.apple.com/library/ios/documentation/cocoa/Reference/Foundation/Classes/NSRunLoop_Class/Reference/Reference.html#//apple_ref/occ/instm/NSRunLoop/run

提到“run”方法,“将接收器置于永久循环中,在此期间它处理来自所有附加输入源的数据。”

现在,在上面的代码中,我没有将任何源附加到 runLoop。它是如何运作的?

ios objective-c multithreading grand-central-dispatch nsrunloop
1个回答
5
投票

每个

NSThread
为了正常工作都需要附加到runloop。当您调用
dispatch_async()
时,GCD 创建带有 runloop 的线程,您可以将其与
[NSRunLoop curentRunLoop]
一起使用。据我了解,当您使用
NSURLConnection
创建一些工作时,创建的连接将作为源附加到当前运行循环。因此,如果您希望 runloop 处于活动状态而不是休眠,则需要执行
[[NSRunLoop curentRunLoop] run]
。在这种情况下,当连接收到消息时,runloop 就会获取该消息。

希望这有帮助。

更新:

通过苹果文档:

performSelector 可以作为输入源

Cocoa 定义了一个自定义输入源,允许您执行 任何线程上的选择器。

这就是为什么你需要执行 keep runlooplive 的原因:

当在另一个线程上执行选择器时,目标线程必须 有一个活跃的运行循环

© www.soinside.com 2019 - 2024. All rights reserved.