使用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阻塞线程的正确写法的更多相关文章

  1. 深入研究 Runloop 与线程保活

    深入研究 Runloop 与线程保活 在讨论 runloop 相关的文章,以及分析 AFNetworking(2.x) 源码的文章中,我们经常会看到关于利用 runloop 进行线程保活的分析,但如果 ...

  2. Java并发读书笔记:如何实现线程间正确通信

    目录 一.synchronized 与 volatile 二.等待/通知机制 等待 通知 面试常问的几个问题 sleep方法和wait方法的区别 关于放弃对象监视器 三.等待通知典型 生产者消费者模型 ...

  3. 解析ThreadPoolExecutor类是如何保证线程池正确运行的

    摘要:对于线程池的核心类ThreadPoolExecutor来说,有哪些重要的属性和内部类为线程池的正确运行提供重要的保障呢? 本文分享自华为云社区<[高并发]通过源码深度解析ThreadPoo ...

  4. obj.style.z-index的正确写法

    obj.style.z-index的正确写法 今天发现obj.style.z-index在js里面报错,后来才知道在js里应该把含"-"的字符写成驼峰式,例如obj.style.z ...

  5. tornado 异步调用系统命令和非阻塞线程池

    项目中异步调用 ping 和 nmap 实现对目标 ip 和所在网关的探测 Subprocess.STREAM 不用担心进程返回数据过大造成的死锁, Subprocess.PIPE 会有这个问题. i ...

  6. 【记录】AutoMapper Project To OrderBy Skip Take 正确写法

    AutoMapper:Queryable Extensions 示例代码: using (var context = new orderEntities()) { return context.Ord ...

  7. IOS RunLoop 常驻线程的实现

    线程常驻,正如其名,我们要实现的事让一个线程长期存在,不被销毁. 这时会有人说,那还不简单吗. 但是这里我们要实现的事如何让线程座椅待命,而且并不是主线程. 首先介绍一下正常情况下的线程使用. // ...

  8. C++中虚继承派生类构造函数的正确写法

    最近工作中某个软件功能出现了退化,追查下来发现是一个类的成员变量没有被正确的初始化.这个问题与C++存在虚继承的情况下派生类构造函数的写法有关.在此说明一下错误发生的原因,希望对更多的人有帮助. 我们 ...

  9. Delphi Socket 阻塞线程下为什么不触发OnRead和OnWrite事件

    //**********************************************************************************//说明: 阻塞线程下为什么不触 ...

随机推荐

  1. html的表单表格...

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  2. insertMany

    结果:

  3. jQuery 事件 - bind() 方法

    定义和用法 bind() 方法为被选元素添加一个或多个事件处理程序,并规定事件发生时运行的函数. 实例1(一个事件) 记得把js引用地址换掉 当点击鼠标时,隐藏或显示 p 元素: <html&g ...

  4. Learning BSD.sys/queue.h

    This file includes 4 data-structures.. Insteresting because they are written in 1994.. to make it ea ...

  5. maven下载,安装与eclipse中maven配置

    1.maven下载.安装与环境变量配置 http://blog.csdn.net/jiuqiyuliang/article/details/45390313 2.Eclipse中maven的配置 ht ...

  6. 八、oracle 分页

    oracle的分页一共有三种方式 方法一 根据rowid来分 SELECT * FROM EMP WHERE ROWID IN (SELECT RID FROM (SELECT ROWNUM RN, ...

  7. 浅谈hbase表中数据导出导入(也就是备份)

    转自:http://blog.chinaunix.net/xmlrpc.php?r=blog/article&uid=23916356&id=3321832 最近因为生产环境hbase ...

  8. Chapter 2 Open Book——10

    I sent that, and began again. 我发送了它,然后又一次重新开始写了. Mom,Everything is great. Of course it's raining. I ...

  9. PHP 5 数据类型

    本页内容来自http://www.runoob.com/php/php-datatypes.html String(字符串), Integer(整型), Float(浮点型), Boolean(布尔型 ...

  10. hdu_2838_Cow Sorting(树状数组求逆序对)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2838 题意:给你一串数,让你排序,只能交换相邻的数,每次交换花费交换的两个树的和,问最小交换的价值 题 ...