gpt4 book ai didi

cocoa - 为什么需要 NSRunLoop 来运行计时器?

转载 作者:行者123 更新时间:2023-12-03 16:28:21 25 4
gpt4 key购买 nike

我买了《Big Nerd Ranch Guide for Objective-C》,但有一些关于 NSRunLoop 的内容我不明白。

这是书中的一段代码:

NSTimer *timer = [NSTimer scheduledTimerWithTimeInterval:2.0 
target:logger
selector:@selector(updateLastTime:)
userInfo:nil
repeats:YES];
[[NSRunLoop currentRunLoop] run];

我的问题是,为什么我需要为要处理的 NSTimer 对象放置一个 NSRunLoop ?为什么它需要放在最后,而不是开头?

为什么它不像其他函数或对象的方法,我只需调用一个函数即可对其进行处理并登录到控制台?

我真的很想弄清楚这里每个细节的每个逻辑。

最佳答案

从早期的 Cocoa 时代开始,当恐龙在地球上漫步、岩石很软、NeXT 工作站还是新事物时,直到 10.6 出现为止,最常见的多任务处理类型是运行循环。这是协作式多任务处理。没有线程。没有抢占式调度程序或内核。没有上下文切换。只有一个大的运行循环说“现在需要做什么?”并运行它。当该事情完成时,它会等待下一个需要做的事情并运行它。它实际上是一个很大的 while(true) 循环。好吧,从技术上讲,代码行是:

for (;;) { ... }

您可以在 CFRunLoop.c 中亲自查看。查找__CFRunLoopRun

NSTimer 就是在那个时候发明的。它所做的一切都是在运行循环中做一个记录,告诉它“当这段时间过去后,请执行此操作”。 (它比这稍微复杂一点,因为它使用 mach 端口,在同一文件中查找 __CFRunLoopTimerSchedule 来了解详细信息,但基本上就是这个想法。)

所以重点是,没有什么魔法。只有一个大的 for(;;) 循环来处理这些东西。必须有东西来运行它。当您启动它(使用 run)时,它不会返回。这是一个无限循环。没有“背景”。没有其他线程。这就是为什么您需要按照 BNR 告诉您的顺序做事。否则你的下一行代码将无法运行。

当然,在 iOS 应用程序和 OS X GUI 应用程序中,您通常不必自己执行此操作。运行循环是在程序启动期间为您创建的,整个主线程都位于其中。这是大多数时候给你打电话的东西。你不叫它。但是,如果您位于主线程以外的线程上,并且想要使用运行循环功能,则必须自己运行它。

如今,很多事情都是通过 GCD 而不是运行循环来完成的。这就是我提到的“直到 10.6 发布”。它确实改变了 cocoa 世界。但大量的 Cocoa 仍然依赖于运行循环,即使你从未想过它,它仍然是大多数应用程序的主力。

在今天的大多数情况下,如果您必须创建一个运行循环才能使用 NSTimer,那么您不应该使用 NSTimer。只需使用dispatch_after。事实上,这就是我今天大部分时间所推荐的,即使您确实有一个运行循环。

(你一定要阅读@quelish 在评论中给出的链接。这是关于运行循环的权威词。)

关于cocoa - 为什么需要 NSRunLoop 来运行计时器?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34169502/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com