在子线程中使用runloop,正确操作NSTimer计时的注意点 三种可选方法
来源:互联网 发布:iphone蜂窝数据快捷键 编辑:程序博客网 时间:2024/06/05 20:45
1、第一种方法 + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo;2、第二种方法NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(newThread) object:nil]; [thread start];
- (void)newThread{ @autoreleasepool { [NSTimer scheduledTimerWithTimeInterval:2.0 target:self selector:@selector(addTime) userInfo:nil repeats:YES]; [[NSRunLoop currentRunLoop] run]; } }3、第三种方法使用了GCD
dispatch_source_t _timers;
uint64_t interval = 0.01 * NSEC_PER_SEC; dispatch_queue_t queue = dispatch_queue_create("my queue", 0); _timers = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue); dispatch_source_set_timer(_timers, dispatch_time(DISPATCH_TIME_NOW, 0), interval, 0); __weak ViewController *blockSelf = self; dispatch_source_set_event_handler(_timers, ^() { NSLog(@"Timer %@", [NSThread currentThread]); [blockSelf addTime]; }); dispatch_resume(_timers);然后再主线程刷新
dispatch_async(dispatch_get_main_queue(), ^{ self.label.text = [NSString stringWithFormat:@"%.2f", self.timeCount/100]; });
切记:千万不要开一个线程,并在其中执行死循环,这时候就得考虑RunLoop机制。
iOS 在子线程中NSTimer的启动和关闭
之前在项目中遇见了一个问题,在子线程中如何开启NSTimer和取消NSTimer。现在总结一下,当做自己的笔记。
1.子线程中NSTimer的开启
首先在.m文件中声明两个属性一个是子线程 一个是子线程中的NSTimer。
@property (nonatomic, strong) NSThread *thread1;@property (nonatomic, strong) NSTimer *threadTimer;
然后用GCD在全局全队中创建一个子线程并创建NSTimer。
__weak __typeof(self) weakSelf = self; dispatch_async(dispatch_get_global_queue(0, 0), ^{ __strong __typeof(weakSelf) strongSelf = weakSelf; if (strongSelf) { strongSelf.thread1 = [NSThread currentThread]; [strongSelf.thread1 setName:@"线程A"]; strongSelf.threadTimer = [NSTimer scheduledTimerWithTimeInterval:1 target:strongSelf selector:@selector(timerAction) userInfo:nil repeats:YES]; NSRunLoop *runloop = [NSRunLoop currentRunLoop]; [runloop addTimer:strongSelf.threadTimer forMode:NSDefaultRunLoopMode]; [runloop run]; } });
注意的是:在子线程中创建的NSTimer需要加入到对应线程的RunLoop中。RunLoop中常用的mode有:NSDefaultRunLoopMode、UITrackingRunLoopMode和NSRunLoopCommonModes三种模式。
NSDefaultRunLoop 默认模式
UITrackingRunLoop 界面追踪,用于scrollView拖拽 滑动
NSRunLoopCommonModes 不是一个特定的模式,只是一种标记,比较综合的一种模式(包含 前两种模式)
在NSTimer加入RunLoop后,需要将RunLoop运行起来。
2.子线程中NSTimer的关闭
之后创建一个cancelTimer的方法
- (void)cancel{if (self.threadTimer) {[self.threadTimer invalidate];self.threadTimer = nil;}}
如果这个方法跟创建NSTimer不在同一个线程执行是无法将Timer 执行invalidate操作的。
然后现在我们需要在thread1这个线程中执行这个操作,在这里写一个方法用于在子线程中调用此方法。
- (void)cancelTimer{if (self.threadTimer && self.thread1) {[self performSelector:@selector(cancel) onThread:self.thread1 withObject:nil waitUntilDone:YES];}}
最后我们在有需要关闭Timer的地方执行此方法即可。
在这里说明一下为什么NSTimer要在同一个线程中创建和关闭。因为创建的Timer的时候已经把Timer加入到该线程对应的RunLoop中,这个RunLoop设置了这个Timer为一个事件。因此要在同一个线程中才能cancel这个Timer。
0 0
- 在子线程中使用runloop,正确操作NSTimer计时的注意点 三种可选方法
- 在子线程中使用runloop,正确操作NSTimer计时的注意点 三种可选方法
- 使用runloop阻塞线程的正确写法
- 使用runloop阻塞线程的正确写法
- 使用runloop阻塞线程的正确写法
- NSTimer 在使用中需要注意的几个问题
- 关于在子线程中在run方法执行完之后通知主线程进行操作的方法。(Toast在子线程中无法使用)
- android-----在子线程中更新UI操作的方法
- 在子线程中操作Ui的几种小方法
- NStimer 在滚动ScrollView的时候停止,在新线程中使用NSTimer
- NStimer 在滚动ScrollView的时候停止,在新线程中使用NSTimer
- IOS在子线程中使用定时器,将定时器添加至RunLoop中(转)
- 在子线程中使用定时器,将定时器添加到RunLoop中
- IOS在子线程中使用定时器,将定时器添加至RunLoop中
- IOS在子线程中使用定时器,将定时器添加至RunLoop中
- IOS在子线程中使用定时器,将定时器添加至RunLoop中
- IOS在子线程中使用定时器,将定时器添加至RunLoop中
- NSTimer 和runloop的问题,将timer加入到runloop----同时注意在viewwilldisappear里面设置为空和无效
- dfs ancient go
- 全对偶测试法1
- 再来一发迪杰斯特拉最短路。HDU2112
- 黑马程序员--面向对象(day05)
- Redis 集群规范(中文稿)(MOVED错误码及ASK错误码
- 在子线程中使用runloop,正确操作NSTimer计时的注意点 三种可选方法
- java动态代理(JDK和cglib)
- 进击的KFC:UI(十)UITableView的编辑和移动
- iOS开发网络篇
- iOS网络-05-AFNetwoking原理及常用操作
- Spring事务传播行为和隔离机制
- poj 3763:Slim Span
- Unity5中的光照简介
- codelity--MaxProductOfThree