iOS NSRunLoop那些事

iOS中timer相关的延时调用,常见的有NSObject中的performSelector:withObject:afterDelay:这个方法在调用的时候会设置当前runloop中timer,还有一种延时,直接使用NSTimer来配置任务。

这两种方式都一个共同的前提,就是当前线程里面需要有一个运行的runloop并且这个runloop里面有一个timer。

我们知道:只有主线程会在创建的时候默认自动运行一个runloop,并且有timer,普通的子线程是没有这些的。这样就带来一个问题了,有些时候我们并不确定我们的模块是不是会异步调用到,而我们在写这样的延时调用的时候一般都不会去检查运行时的环境,这样在子线程中被调用的时候,我们的代码中的延时调用的代码就会一直等待timer的调度,但是实际上在子线程中又没有这样的timer,这样我们的代码就永远不会被调到。

下面的代码展示了performSelector和dispatch_time的不同

  1. /*
  2. 采用gcd的方式 延时添加到队列
  3. */
  4. -(void) testDispatch_after{
  5. dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3*NSEC_PER_SEC);
  6. dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
  7. dispatch_after(time, queue, ^{
  8. NSLog(@"3秒后添加到队列");
  9. });
  10. dispatch_release(queue);
  11. }
  12. -(void) testDelay{
  13. NSLog(@"testDelay被执行");
  14. }
  15. /*
  16. dispatch_barrier_async 栅栏的作用
  17. */
  18. -(void) testDispatch_Barrier{
  19. //dispatch_queue_t gcd = dispatch_queue_create("这是序列队列", NULL);
  20. dispatch_queue_t gcd = dispatch_queue_create("这是并发队列", DISPATCH_QUEUE_CONCURRENT);
  21. dispatch_async(gcd, ^{
  22. NSLog(@"b0");
  23. //这个selector不会执行,因为线程中没有runloop
  24. [self performSelector:@selector(testDelay) withObject:nil afterDelay:3];
  25. //代码会执行,因为采用了gcd方式
  26. [self testDispatch_after];
  27. });
  28. dispatch_release(gcd);
  29. }

在有多线程操作的环境中,这样performSelector的延时调用,其实是缺乏安全性的。我们可以用另一套方案来解决这个问题,就是使用GCD中的dispatch_after来实现单次的延时调用

另外有一个解决方案:

performSelector并不是没有办法保证线程安全。例如下面的代码就可以运行:

  1. [self performSelector:@selector(testDelay) onThread:[NSThread mainThread] withObject:nil waitUntilDone:NO];

指定了该selector在主线程中运行。

还有一个解决方案:

  1. [self performSelector:@selector(testDelay) withObject:nil afterDelay:3 inModes:[NSArray arrayWithObject:NSDefaultRunLoopMode]];
  2. [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];

启动线程中runloop,因为每个线程就有个默认的runloop

时间: 2024-10-29 19:08:25

iOS NSRunLoop那些事的相关文章

ios:NSRunLoop

ios:NSRunLoop 1.NSRunLoop是消息机制的处理模式 NSRunLoop的作用在于有事情做的时候使的当前NSRunLoop的线程工作,没有事情做让当前NSRunLoop的线程休眠 2.nstimer默认添加到当前NSRunLoop中,也可以手动制定添加到自己新建的NSRunLoop的中 [NSTimer schduledTimerWithTimeInterval: target:selector:userInfo:repeats]; 此方法默认添加到当前NSRunLoop中 N

从cocos2dx源代码看android和iOS跨平台那些事

cocos2dx一个跨移动(平板)平台的游戏引擎,支持2d和3d,基于c/c++,网上介绍多在此不详叙.我们本篇关心的是跨平台那些事,自然而然就找到platform目录.好家伙,支持的操作平台还真不少,最吸引我们关注的可能就是字母顺序排列的头二个平台,android和apple.然后顺带会看一看winrt和linux.platform这个目录,物如其名,就是一些使用到平台服务的东西(封装).platform目录下各平台子目录封装的平台服务都大同小异,唯android目录特殊还多了jni和java

iOS 证书那些事

关于开发证书配置(Certificates & Identifiers & Provisioning Profiles),相信做iOS开发的同学没少被折腾.对于一个iOS开发小白.半吊子(比如像我自己)抑或老兵,或多或少会有或曾有过以下不详.疑问.疑惑甚至困惑: 什么是App ID?Explicit/Wildcard App ID有何区别?什么是App Group ID? 什么是证书(Certificate)?如何申请?有啥用? 什么是Key Pair(公钥/私钥)?有啥用?与证书有何关联

iOS开发那些事-iOS6苹果地图有用开发

在iOS 6之后,不再使用谷歌地图了,而是使用苹果自己的地图,可是API编程接口没有太大的变化.开发者不须要再学习非常多新东西就能开发地图应用,这是负责任的做法.因此本节介绍的内容也相同适用于iOS5上执行地图应用开发. iOS应用程序中使用Map Kit API开发地图应用程序. 其核心是MKMapView类使用.我们能够设置地图显示方式.控制地图,能够在地图上加入标注. 显示地图 在Map Kit API中显示地图的视图是MKMapView,它的托付协议是MKMapViewDelegate.

iOS开发那些事-iOS6苹果地图实用开发

在iOS 6之后,不再使用谷歌地图了,而是使用苹果自己的地图,但是API编程接口没有太大的变化.开发人员不需要再学习很多新东西就能开发地图应用,这是负责任的做法.因此本节介绍的内容也同样适用于iOS5上运行地图应用开发. iOS应用程序中使用Map Kit API开发地图应用程序. 其核心是MKMapView类使用.我们可以设置地图显示方式.控制地图,可以在地图上添加标注. 显示地图 在Map Kit API中显示地图的视图是MKMapView,它的委托协议是MKMapViewDelegate.

iOS 圆角那些事

iOS开发中各种圆角也随处可见,最简单给控件添加圆角的方式就是给视图的layer设置corner属性了: [Objective-C] 查看源文件 复制代码 ? 1 2 self.blueView.layer.cornerRadius = 5.f; self.blueView.layer.masksToBounds = YES; 这种方式会带来两个问题: 当图片数量比较多的时候,这种添加圆角方式特别消耗性能,比如在UITableViewCell添加过多圆角的话,甚至会带来视觉可见的卡顿. 无法配置

ios tableView那些事

iOS开发很重要的一个功能就是tableView,可以说熟练使用tableView是iOS开发必修的课程,网上很多相关介绍,推荐一个博客参考一下: http://blog.csdn.net/lengshengren/article/details/10439637 相关博客35篇.

iOS开发你不知道的事-编译&链接

对于平常的应用程序开发,我们很少需要关注编译和链接过程.我们平常Xcode开发就是集成的的开发环境(IDE),这样的IDE一般都将编译和链接的过程一步完成,通常将这种编译和链接合并在一起的过程称为构建,即使使用命令行来编译一个源代码文件,简单的一句gcc hello.c命令就包含了非常复杂的过程! 正是因为集成开发环境的强大,很多系统软件的运行机制与机理被掩盖,其程序的很多莫名其妙的错误让我们无所适从,面对程序运行时种种性能瓶颈我们束手无策.我们看到的是这些问题的现象,但是却很难看清本质,所有这

IOS —— 网络那些事(上) - http协议

作为一名并不太合格的程序员,今天要分享学习的成果,竟然讲的是网络相关HTTP协议的事情.(也算是复习了) 乍看HTTP协议的内容着实是十分复杂的,涉及到十分多互联网"底层"框架的东西.今天就先撇开这部分详细内容. 简单的来说说HTTP协议,以及连接的事项. HTTP协议发展至今也有二十多年历史,版本也从原来的1.0 进化到了2.0 那么还是一如既往,图文理解比较简单. 以下图片以"下单"表示客户端向服务器端发送数据 以"发货"表示服务器端对客户端