使用runloop阻塞线程的正确写法
使用runloop阻塞线程的正确写法
runloop可以阻塞线程,等待其他线程执行后再执行。
比如:
@implementation ViewController{
BOOL end;
}
…
– (void)viewDidLoad
{
[super viewDidLoad];
NSLog(@”start new thread …”);
[NSThread detachNewThreadSelector:@selector(runOnNewThread) toTarget:self withObject:nil];
while (!end) {
NSLog(@”runloop…”);
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
NSLog(@”runloop end.”);
}
NSLog(@”ok.”);
}
-(void)runOnNewThread{
NSLog(@”run for new thread …”);
sleep(1);
end=YES;
NSLog(@”end.”);
}
但是这样做,运行时会发现,while循环后执行的语句会在很长时间后才被执行。
那是不是可以这样:
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
缩短runloop的休眠时间,看起来解决了上面出现的问题。
不过这样也又问题,runloop对象被经常性的唤醒,这违背了runloop的设计初衷。runloop的作用就是要减少cpu做无谓的空转,cpu可在空闲的时候休眠,以节约电量。
那么怎么做呢?正确的写法是:
-(void)runOnNewThread{
NSLog(@”run for new thread …”);
sleep(1);
[self performSelectorOnMainThread:@selector(setEnd) withObject:nil waitUntilDone:NO];
NSLog(@”end.”);
}
-(void)setEnd{
end=YES;
}
见黑体斜体字部分,要将直接设置变量,改为向主线程发送消息,执行方法。问题得到解决。
这里要说一下,造成while循环后语句延缓执行的原因是,runloop未被唤醒。因为,改变变量的值,runloop对象根本不知道。延缓的时长总是不定的,这是因为,有其他事件在某个时点唤醒了主线程,这才结束了while循环。那么,向主线程发送消息,将唤醒runloop,因此问题就解决了。
使用runloop阻塞线程的正确写法的更多相关文章
- 深入研究 Runloop 与线程保活
深入研究 Runloop 与线程保活 在讨论 runloop 相关的文章,以及分析 AFNetworking(2.x) 源码的文章中,我们经常会看到关于利用 runloop 进行线程保活的分析,但如果 ...
- Java并发读书笔记:如何实现线程间正确通信
目录 一.synchronized 与 volatile 二.等待/通知机制 等待 通知 面试常问的几个问题 sleep方法和wait方法的区别 关于放弃对象监视器 三.等待通知典型 生产者消费者模型 ...
- 解析ThreadPoolExecutor类是如何保证线程池正确运行的
摘要:对于线程池的核心类ThreadPoolExecutor来说,有哪些重要的属性和内部类为线程池的正确运行提供重要的保障呢? 本文分享自华为云社区<[高并发]通过源码深度解析ThreadPoo ...
- obj.style.z-index的正确写法
obj.style.z-index的正确写法 今天发现obj.style.z-index在js里面报错,后来才知道在js里应该把含"-"的字符写成驼峰式,例如obj.style.z ...
- tornado 异步调用系统命令和非阻塞线程池
项目中异步调用 ping 和 nmap 实现对目标 ip 和所在网关的探测 Subprocess.STREAM 不用担心进程返回数据过大造成的死锁, Subprocess.PIPE 会有这个问题. i ...
- 【记录】AutoMapper Project To OrderBy Skip Take 正确写法
AutoMapper:Queryable Extensions 示例代码: using (var context = new orderEntities()) { return context.Ord ...
- IOS RunLoop 常驻线程的实现
线程常驻,正如其名,我们要实现的事让一个线程长期存在,不被销毁. 这时会有人说,那还不简单吗. 但是这里我们要实现的事如何让线程座椅待命,而且并不是主线程. 首先介绍一下正常情况下的线程使用. // ...
- C++中虚继承派生类构造函数的正确写法
最近工作中某个软件功能出现了退化,追查下来发现是一个类的成员变量没有被正确的初始化.这个问题与C++存在虚继承的情况下派生类构造函数的写法有关.在此说明一下错误发生的原因,希望对更多的人有帮助. 我们 ...
- Delphi Socket 阻塞线程下为什么不触发OnRead和OnWrite事件
//**********************************************************************************//说明: 阻塞线程下为什么不触 ...
随机推荐
- LeetCode OJ 33. Search in Rotated Sorted Array
Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 migh ...
- UNIX基础--控制台和终端
虚拟控制台和终端 Virtual Consoles and Terminals: FreeBSD 虚拟控制台的默认配置为8个,但并不是硬性设置, 您可以很容易设置虚拟控制台的个数增多或减少. 虚拟控制 ...
- OAuth流程
简介 OAuth是一种协议,OAuth协议为用户资源的授权提供了一个安全的.开放而又简易的标准 第三方若想访问用户资源,就必须遵守服务提供商实现的OAuth协议 OAuth授权的步骤(新浪微博为例) ...
- wpf ListBox 双击事件时在子项添加Style 确保选中
<ListBox ItemTemplate="{StaticResource CardPictureTemplate}" VirtualizingPanel.CacheLen ...
- mnesia
1.模式创建 mnesia:create_schema([node()|nodes()]).集群的节点之间创建模式 2.启动和停止 application:start(mnesia). applica ...
- AltiumDesigner14绘制四层板设置
1,快捷键(O+K)进入板层设置界面: 2,选择AddLayer,里边有两个选项(add layer(添加信号层)||add internal plane(增加平面)) 四层板的话一般层次的划分是t ...
- COM与.NET程序集导出和部署COM组件
为了分布式和多客户端调用我们还需要将写好的COM组件发布到一台服务器上.这里我们将组件部署到操作系统的COM+应用程序中去.如果没此需要就可以导出后,在C++环境中调用COM了. 第一步:导出COM组 ...
- Find and run the whalesay image
Find and run the whalesay image People all over the world create Docker images. You can find these i ...
- 在VS中生成后拷贝文件
环境:win7_64旗舰版,VS2013 工作项目中,一般会使用第三方库,当修改并重新编译第三方库后,需要将DLL文件拷贝到工作项目下的生成目录中,每次手动拷贝比较繁琐,VS提供自定义生成事件,允许我 ...
- c/s架构
C/S 结构,即大家熟知的客户机和服务器结构.它是软件系统体系结构,通过它可以充分利用两端硬件环境的优势,将任务合理分配到Client端和Server端来实现,降低了系统的通讯开销.目前大多数应用软件 ...