菜鸟教程小白 发表于 2022-12-12 11:49:47

ios - 何时使用 dispatch_get_main_queue


                                            <p><p>我在 iOS 中学到了一条全局规则 -> 永远不要阻塞主线程。
但是,有几次我遇到了违反此规则的开源代码片段。 </p>

<p>下面是两个这样的例子:</p>

<p>以下函数取自
<a href="https://github.com/piwik/piwik-sdk-ios/blob/master/PiwikTracker/PiwikTracker.m" rel="noreferrer noopener nofollow">https://github.com/piwik/piwik-sdk-ios/blob/master/PiwikTracker/PiwikTracker.m</a> </p>

<pre>- (void)startDispatchTimer {

//在主线程运行循环
__weak typeof(self)weakSelf = self;
dispatch_async(dispatch_get_main_queue(), ^{

    ;

   //如果调度间隔为 0) {

   //在计时器上运行
      weakSelf.dispatchTimer = [NSTimer scheduleTimerWithTimeInterval:weakSelf.dispatchInterval
                                                                目标:弱 self
                                                            选择器:@选择器(调度:)
                                                            用户信息:无
                                                               重复:否];

      NSLog(@"Dispatch timer 以间隔 %f 开始", weakSelf.dispatchInterval);

    }

});

}
</pre>

<p>在上面的代码中,我一直试图理解为什么计时器对象需要主线程。像这样的事情与 UI 无关,仍然在主线程上完成。 </p>

<p>另一个例子是著名的网络库 MKNetworkKit。
以下代码在 NSOperation 的 start 方法中。
<a href="https://github.com/MugunthKumar/MKNetworkKit/blob/master/MKNetworkKit/MKNetworkOperation.m" rel="noreferrer noopener nofollow">https://github.com/MugunthKumar/MKNetworkKit/blob/master/MKNetworkKit/MKNetworkOperation.m</a> </p>

<上一页>

dispatch_async(dispatch_get_main_queue(), ^{
      self.connection = [ initWithRequest:self.request
                                                      代表:自己
                                                立即开始:否];

      
                                 forMode:NSRunLoopCommonModes];

      ;
    });
</pre>

<p>所以我的问题是为什么人们使用主线程来执行不与 UI 相关的操作,它有什么好处。如果您不坚持它,它可能不会卡住您的应用程序,但为什么要冒险。 </p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>这两个例子都直接或间接地使用了 NSRunLoop 方法。在这些情况下,您应该从执行目标 NSRunLoop 的线程中调用方法。因此你需要 dispatch_get_main_queue()。</p>

<p>看看苹果关于NSRunLoop的文档<a href="https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/classes/nsrunloop_class/reference/reference.html" rel="noreferrer noopener nofollow">https://developer.apple.com/library/ios/documentation/cocoa/reference/foundation/classes/nsrunloop_class/reference/reference.html</a> </p>

<blockquote>
<p>Warning: The NSRunLoop class is generally not considered to be thread-safe and its methods should only be called within the context of the current thread. You should never try to call the methods of an NSRunLoop object running in a different thread, as doing so might cause unexpected results.</p>
</blockquote>

<p>顺便说一句,NSRunLoop 似乎在 Core Foundation 中使用了 CFRunLoop,而 Core Foundation 是在 Apple 的开源许可下发布的。</p>

<p> <a href="http://opensource.apple.com/source/CF/CF-855.17/CFRunLoop.c" rel="noreferrer noopener nofollow">http://opensource.apple.com/source/CF/CF-855.17/CFRunLoop.c</a> </p>

<p>似乎 CFRunLoop 是线程安全的(我们可以看到很多 __CFRunLoopLock 和 __CFRunLoopUnlock 组合)。但无论如何你最好遵守文件:)</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - 何时使用 dispatch_get_main_queue,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/25795565/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/25795565/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - 何时使用 dispatch_get_main_queue