Ios 调用(NSRunLoop)-run()和CFRunLoopRun()之间有什么区别
我正在学习iOS runloop。网上的一些文章向我展示了如下代码:Ios 调用(NSRunLoop)-run()和CFRunLoopRun()之间有什么区别,ios,multithreading,runloop,Ios,Multithreading,Runloop,我正在学习iOS runloop。网上的一些文章向我展示了如下代码: -(无效)内存发布{ 对于(int i=0;i
-(无效)内存发布{
对于(int i=0;i<10000;i++){
NSThread*thread=[[NSThread alloc]initWithTarget:self selector:@selector(runThread)object:nil];
[线程集名称:线程名称];
[线程开始];
[自执行选择器:@selector(stopThread)onThread:thread,对象为nil waituntldone:YES];
}
}
-(void)runThread{
NSLog(@“当前线程=%@,[NSThread currentThread]);
NSRunLoop*runLoop=[NSRunLoop currentlunloop];
静态端口*端口;
如果(!端口){
端口=[NSMachPort端口];
}
[runLoop addPort:port forMode:NSDefaultRunLoopMode];
//CFRunLoopRun();//好的
[运行循环运行];//⚠️线程未退出。。。!
}
-(无效)止动螺纹{
CFRunLoopStop(CFRunLoopGetCurrent());
NSThread*thread=[NSThread currentThread];
[线程取消];
}
使用CFRunLoopRun()
时,一切正常。在每个for循环中,创建一个线程,然后退出。但是对于[runLoop run]
,内存不断增长,最终应用程序终止,原因是“-[NSThread start]:线程创建失败,出现错误35”(达到线程计数上限?)
**我的问题:
-run()
和CFRunLoopRun()
之间有什么区别?我以为前者只是后者的包装CFRunLoopRun
文档告诉我们:
当前线程的运行循环在默认模式下运行(请参见默认运行循环模式),直到运行循环使用CFRunLoopStop
停止,或者从默认运行循环模式中删除所有源和计时器
但是运行
没有提到这一点。它说:
如果没有输入源或计时器连接到运行循环,则此方法立即退出;否则,它将通过重复调用以NSDefaultRunLoopMode
运行接收器。换句话说,该方法有效地开始了一个无限循环,该循环处理来自运行循环的输入源和计时器的数据
但它接着警告说:
手动从运行循环中删除所有已知输入源和计时器并不能保证运行循环将退出。macOS可以根据需要安装和删除其他输入源,以处理针对接收方线程的请求。因此,这些源可以阻止运行循环退出
如果希望运行循环终止,则不应使用此方法。相反,使用其他运行方法之一,并在循环中检查自己的其他任意条件。一个简单的例子是:
BOOL shouldKeepRunning = YES; // global
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
其中,shouldKeepRunning
在程序的其他地方设置为NO
我还建议你参考一下
你问:
代码似乎意在显示退出线程的正确方法。它在实际开发中实用吗
不,现在很少再编写自己的NSThread
代码了。(GCD)消除了所有这些麻烦。它效率更高(因为它有一个随时可用的工作线程池,不需要每个线程都有一个旋转循环或nsrunlop
),而且编写代码要容易得多。我不建议编写NSThread
代码,除非有一些非常特殊的问题,您无法用GCD轻松解决
顺便说一下,请注意,当您编写
NSThread
代码时,您应该真正拥有自己的线程(尽管我们使用@autoreleasepool{…}
而不是该指南中概述的模式)。例如:
- (void)runThread {
@autoreleasepool {
...
}
}
如果您使用GCD,那么这个内存管理将由您负责
如果需要有关
NSThread
、nsrunlop
等的详细信息,请参阅。或者省去很多痛苦,直接使用。CFRunLoopRun文档告诉我们:
当前线程的运行循环在默认模式下运行(请参见默认运行循环模式),直到运行循环使用CFRunLoopStop
停止,或者从默认运行循环模式中删除所有源和计时器
但是运行
没有提到这一点。它说:
如果没有输入源或计时器连接到运行循环,则此方法立即退出;否则,它将通过重复调用以NSDefaultRunLoopMode
运行接收器。换句话说,该方法有效地开始了一个无限循环,该循环处理来自运行循环的输入源和计时器的数据
但它接着警告说:
手动从运行循环中删除所有已知输入源和计时器并不能保证运行循环将退出。macOS可以根据需要安装和删除其他输入源,以处理针对接收方线程的请求。因此,这些源可以阻止运行循环退出
如果希望运行循环终止,则不应使用此方法。相反,使用其他运行方法之一,并在循环中检查自己的其他任意条件。一个简单的例子是:
BOOL shouldKeepRunning = YES; // global
NSRunLoop *theRL = [NSRunLoop currentRunLoop];
while (shouldKeepRunning && [theRL runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]]);
其中,shouldKeepRunning
在程序的其他地方设置为NO
我还建议你参考一下
你问:
代码似乎意在显示退出线程的正确方法。它在实际开发中实用吗
不,现在很少再编写自己的NSThread
代码了。(GCD)消除了所有这些麻烦。它效率更高(因为它有一个随时可用的工作线程池,不需要每个线程都有一个旋转循环或nsrunlop
),而且编写代码要容易得多。我不会建议你