如果没有源,GCD块中的runLoop如何工作

时间:2014-07-16 11:13:21

标签: ios objective-c multithreading grand-central-dispatch nsrunloop

我试图理解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

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

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

1 个答案:

答案 0 :(得分:2)

正常工作的每个NSThread都需要附加到runloop。当你致电dispatch_async() GCD时,用runloop创建一个你将与[NSRunLoop curentRunLoop]一起使用的线程。当您使用NSURLConnection创建一些工作时,据我所知,创建的连接作为源附加到当前的runloop。因此,如果你不想让runloop活着并且不要入睡,你需要执行[[NSRunLoop curentRunLoop] run]。在这种情况下,runloop将在连接收到消息时收到消息。

希望这有帮助。

<强>更新

通过Apple文档:

performSelector可以是输入源

  

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

这就是你需要保持runloop活着的原因:

  

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