Ios 何时使用dispatch\u get\u main\u队列

Ios 何时使用dispatch\u get\u main\u队列,ios,asynchronous,grand-central-dispatch,mknetworkkit,Ios,Asynchronous,Grand Central Dispatch,Mknetworkkit,我在iOS->中学会了一条全局规则:永远不要阻止主线程。 然而,有几次我遇到了违反此规则的开源代码片段 以下是两个这样的例子: 以下函数取自 -(无效)开始喷洒时间{ //在主线程运行循环上运行 __弱类型(自我)弱自我=自我; dispatch\u async(dispatch\u get\u main\u queue()^{ [weakSelf stopDispatchTimer]; //如果调度间隔为0){ //定时运行 weakSelf.dispatchTimer=[NSTimer s

我在iOS->中学会了一条全局规则:永远不要阻止主线程。 然而,有几次我遇到了违反此规则的开源代码片段

以下是两个这样的例子:

以下函数取自

-(无效)开始喷洒时间{ //在主线程运行循环上运行 __弱类型(自我)弱自我=自我; dispatch\u async(dispatch\u get\u main\u queue()^{ [weakSelf stopDispatchTimer]; //如果调度间隔为0){ //定时运行 weakSelf.dispatchTimer=[NSTimer scheduledTimerWithTimeInterval:weakSelf.dispatchInterval 目标:懦夫 选择器:@selector(分派:) 用户信息:无 重复:否]; NSLog(@“调度计时器以间隔%f启动”,弱自调度间隔); } }); } 在上面的代码中,我一直试图理解为什么计时器对象需要主线程。这样的事情与UI无关,仍然在主线程上完成

另一个例子是著名的网络库MKNetworkKit。 其中,以下代码位于NSOperation的start方法中。

dispatch\u async(dispatch\u get\u main\u queue()^{ self.connection=[[NSURLConnection alloc]initWithRequest:self.request 代表:赛尔夫 立即开始:没有]; [self.connection scheduleinruop:[NSRunLoop currentRunLoop] forMode:nsrunlopCommonModes]; [自连接启动]; });
所以我的问题是,为什么人们使用主线程来执行与UI无关的操作,以及它带来了什么好处。如果你没有抓住它,它可能不会冻结你的应用程序,但为什么要冒险呢

两个示例都直接或间接使用nsrunlop方法。在这些情况下,应该从执行目标nsrunlop的线程调用方法。因此,您需要dispatch\u get\u main\u queue()

请查看有关nsrunlop的apple文档

警告:nsrunlop类通常不被认为是线程安全的,其方法只能在当前线程的上下文中调用。千万不要尝试调用在不同线程中运行的NSRunLoop对象的方法,因为这样做可能会导致意外结果

顺便说一下,NSRunLoop似乎在核心基础上使用CFRUNROLL,而核心基础是在苹果的开源许可下发布的。


看起来CFRunLoop是线程安全的(我们可以看到很多uucfrunlooplock和uucfrunloopunlock的组合)。但是你最好还是遵守文档:)

我同意,但是人们可以创建一个不同的线程,并在该线程中安排一个新的运行循环。他们为什么使用属于主线程的运行循环?完全正确。我想其中一个原因是,除了Dispatch_get_main_queue和main runloop之外,没有其他方便的方式通过Grand Central Dispatch实现这一点。如果我们可以创建一个串行队列,并在串行队列线程上运行一个runloop,那么我肯定会使用它。 - (void)startDispatchTimer { // Run on main thread run loop __weak typeof(self)weakSelf = self; dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf stopDispatchTimer]; // If dispatch interval is 0) { // Run on timer weakSelf.dispatchTimer = [NSTimer scheduledTimerWithTimeInterval:weakSelf.dispatchInterval target:weakSelf selector:@selector(dispatch:) userInfo:nil repeats:NO]; NSLog(@"Dispatch timer started with interval %f", weakSelf.dispatchInterval); } }); } dispatch_async(dispatch_get_main_queue(), ^{ self.connection = [[NSURLConnection alloc] initWithRequest:self.request delegate:self startImmediately:NO]; [self.connection scheduleInRunLoop:[NSRunLoop currentRunLoop] forMode:NSRunLoopCommonModes]; [self.connection start]; });