- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在学习 iOS runloop。网上的一些文章向我展示了这样的代码:
- (void)memoryIssue {
for (int i = 0; i < 10000; i++) {
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(runThread) object:nil];
[thread setName:thread_name];
[thread start];
[self performSelector:@selector(stopThread) onThread:thread withObject:nil waitUntilDone:YES];
}
}
- (void)runThread {
NSLog(@"current thread = %@", [NSThread currentThread]);
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
static NSMachPort *port;
if (!port) {
port = [NSMachPort port];
}
[runLoop addPort:port forMode:NSDefaultRunLoopMode];
// CFRunLoopRun(); //All right
[runLoop run]; // ⚠️Thread not exit...!
}
- (void)stopThread {
CFRunLoopStop(CFRunLoopGetCurrent());
NSThread *thread = [NSThread currentThread];
[thread cancel];
}
当使用 CFRunLoopRun()
时,一切正常。在每个 for 循环中,都会创建一个线程,然后退出。然而对于[runLoop run]
,内存不断增长,最终应用程序由于“-[NSThread start]: Thread creation failed with error 35”(达到线程数上限?)而终止。
**我的问题:
-run()
和 CFRunLoopRun()
有什么区别?我认为前者只是后者的包装。
这段代码似乎是想展示退出线程的正确方法。在实际开发中是否实用?**
最佳答案
CFRunLoopRun
文档告诉我们:
The current thread’s run loop runs in the default mode (see Default Run Loop Mode) until the run loop is stopped with
CFRunLoopStop
or all the sources and timers are removed from the default run loop mode.
但是运行
documentation没有提及这一点。它说:
If no input sources or timers are attached to the run loop, this method exits immediately; otherwise, it runs the receiver in the
NSDefaultRunLoopMode
by repeatedly invokingrunMode:beforeDate:
. In other words, this method effectively begins an infinite loop that processes data from the run loop’s input sources and timers.
但它继续警告:
Manually removing all known input sources and timers from the run loop is not a guarantee that the run loop will exit. macOS can install and remove additional input sources as needed to process requests targeted at the receiver’s thread. Those sources could therefore prevent the run loop from exiting.
If you want the run loop to terminate, you shouldn't use this method. Instead, use one of the other run methods and also check other arbitrary conditions of your own, in a loop. A simple example would be:
BOOL shouldKeepRunning = YES; // global
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);where
shouldKeepRunning
is set toNO
somewhere else in the program.
我还建议您引用 Threading Programming Guide: Terminating a Thread .
你问:
The code seems to intend to show the right way to exit a thread. Is it practical in real-life developing?
不,编写我们自己的 NSThread
代码已经非常少见了。 Grand Central Dispatch (GCD) 消除了所有这些麻烦。它更高效(因为它有准备就绪的工作线程池,不需要旋转循环或每个线程的 NSRunLoop
等)并且更容易编写代码。我不建议编写 NSThread
代码,除非存在一些您无法使用 GCD 轻松解决的非常具体的问题。
顺便说一下,注意当你写NSThread
代码的时候,你真的应该有你的线程set up its own autorelease pool (虽然我们会使用 @autoreleasepool { ... }
而不是该指南中概述的模式)。例如:
- (void)runThread {
@autoreleasepool {
...
}
}
如果您使用 GCD,此内存管理会为您处理。
如果您想了解有关 NSThread
、NSRunLoop
等的更多信息,请参阅 Threading Programming Guide .或者使用 GCD 为自己省去很多痛苦.
关于ios - 调用 (NSRunLoop)-run() 和 CFRunLoopRun() 有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55811820/
我已经通过 AVD 管理器启动了我的模拟器,一旦它运行,我点击了 run app。我已经等了几分钟,我的正在运行的设备出现在 选择一个正在运行的设备 中,但窗口始终保持空白。 最佳答案 您正在运行的项
我想在安装新数据库之前删除旧数据库,以便为用户更新它。 我有以下情况: 在我的 Components 部分中,我为用户提供了一个选项: [Components] Name: "updateDataba
如果我将一个 Python 模块实现为一个目录(即包),它同时具有顶级函数 run 和子模块 run,我可以指望 from example import run 总是导入函数?根据我的测试,至少在 L
我在 Eclipse Juno 上使用 Tomcat 7。我使用工作区元数据作为服务器位置(请参阅下面的我的 tomcat 配置)。 我也收到了 服务器项目在 eclipse [请看下图] 中使用单独
我正在做一些测试以了解 java 中的不同线程状态,并且遇到了一些查询。 通常,当一个线程被实例化时,它被称为处于 "NEW" 状态,然后当调用它的 start() 方法时,操作系统调度程序获得控制权
当我使用命令 npm run build -- --prod 时,我收到以下错误消息: 属性“PropertyName1”是私有(private)属性,只能在“AppComponent”类中访问 “A
我正在尝试将默认的“运行”键盘快捷键更改为 ⌘R。 - 因为我不想每次都伸手去拿触控板,而且我的手指不够长,无法一次执行⌥⇧F10。 “运行”和“运行...”有什么区别? 最佳答案 ... 用于菜单中
我现在不知道如何编写一个合适的方法来测试这种行为。请不要投反对票.. 我现在有一个 java 类负责处理数据并将数据添加到多个数据库。每个数据库都保存相同的数据,但处理方式不同(例如,以不同的插值率进
我知道不应该调用 run 方法来启动新线程执行,但我指的是 this article他们在另一个 run 方法中调用了 runnable.run(); ,这似乎暗示它启动了一个新线程或者根本没有cre
当我尝试在Windows 10/11下使用Eclipse 2023-06调试任何应用程序(甚至是hello.c)时,我总是收到以下错误:。该错误清楚地指示-(错误2)-路径是错误的。。我试图在互联网上
在运行vue文件时,需要进行npm操作,但我们发现,有时候用的是npm run serve,而有的时候用的是npm run dev,二者有什么区别 在我们运行一些 vue 项目的时候,输入npm ru
我想在 cloud run 上运行一个长时间运行的作业。该任务可能执行超过 30 分钟,并且主要发送 API 请求。cloud run 在大约 20 分钟后停止执行,从指标来看,它似乎没有识别出我的任
我们无法让 SSE 从 Google Cloud Run 上的容器发送。我已经尝试使用一个简单的 SSE 示例( https://github.com/kljensen/node-sse-exampl
直到最近,我一直在执行这个美丽来构建 + 运行一个带有堆栈的项目: stack build && .stack-work/install/x86_64-linux/lts-4.1/7.10.3/bin
我们有一个小脚本,可以抓取网页(约 17 个条目),并将它们写入 Firestore 集合。为此,我们在 Google Cloud Run 上部署了一项服务。 这段代码的执行需要大约 5 秒 when
我是Docker的新手,我知道一种运行交互式容器的方法如下: $ docker run -it image-name bash 要么 $ docker run -it image-name /bin/
Dockerfile 中的多个 RUN 条目之间有什么区别,例如: FROM php:5.6-apache RUN docker-php-ext-install mysqli RUN apt upda
对于来自文档的云运行内存使用情况 ( https://cloud.google.com/run/docs/configuring/memory-limits ) Cloud Run applicati
今天早上我更新了我的 Ubuntu 版本,现在我无法从 eclipse 运行我的应用程序。 问题是,当我单击“运行方式”时出现的列表是空的,我无法运行任何内容。 我该如何解决这个问题? 我能看到的唯一
我正在 intelliJ 上使用 livereload 测试 spring-boot-devtools。我有一个简单的 SpringBootApplication,可以正常工作。 当我从 maven
我是一名优秀的程序员,十分优秀!