单独线程上使用RunLoop开启NSTimer

//第一步:创建一个新的子线程,为了不阻塞当前线程
- (NSThread *)archiveringThread {
      static NSThread *_thread = nil;
      static dispatch_once_t onceToken;
      __weak __typeof(self)weakSelf = self;
      dispatch_once(&onceToken, ^{
          __strong __typeof(weakSelf)strongSelf = weakSelf;

          //1.  创建新的NSThread对象
          _thread = [[NSThread alloc] initWithTarget:self                                selector:@selector(threadStartRunMethod:)                            object:nil];

          //2. 注意,一定要start线程对象,否则不执行
          [_thread start];
      };
      return _thread;
}                                        
// 第二步:在新线程对象的执行函数里面,开启新线程对象的runloop
- (void) threadStartRunMethod:(id)__unused object {
    //注意:这个方法执行是在新的子线程上,并不是当前线程对象

    // 设置线程的名字
    NSThread *thread = [NSThread currentThread];
    [thread setName:@"所在新的子线程对象"];

    // 获取当前所在线程对象的runloop
    NSRunloop *runLoop = [NSRunLoop currentRunLoop];
    [runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode];

    // 开启runloop,开始接收事件源
    [runLoop run];
}
// 第三步:在创建的新线程上,执行startArchiverData方法
- (void)scheduleArchive {
    [self performSelector:@selector(startArchiverData) onThread:[self archiveringThread] withObject:nil waitUntilDone:NO modes:[self.runLoopModes allObjects]];
}
// 第四步:在所在的runloop添加NSTimer时间, 一直让runloop处于接收事件源的状态

- (void)startArchiverData {
    //1. 获取当前线程的runloop
    NSRunLoop *loop = [NSRunLoop currentRunLoop];

    //.2 创建NSTimer,指定回调函数doArchiverData
    _archiveringTimer = [NSTimer timerWithTimeInterval:10.f target:self selector:@selector(doArchiverData) userInfo:nil repeats:YES];

    //3. 将NSTimer添加到runloop
    [loop addTimer:_archiveringTimer forMode:NSDefaultRunLoopMode];

    //4. 一直让loop执行timer事件源
    while (YES) {
        [loop runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:2.f]];
    }
}
// 第五步:有runloop调度执行NSTimer的回调函数
- (void)doArchiverData {
    NSLog(@"... doArchiverData ... \n");
}
时间: 2024-11-04 23:36:33

单独线程上使用RunLoop开启NSTimer的相关文章

iOS学习——RUNLOOP、NSTimer

每一个app的启动,开启主线程的同时,也开启了一个Runloop死循环,runloop会不断询问是否有新的任务给线程执行.runloop最常用的三块,就是网络事件,事件响应与NSTimer.网络事件现在基本上都用已经封装好的框架,但是最初用NSURLConnection进行网络请求的时候,会出现异步回调永远没法回来的情况,原因就是子线程运行完了,不会再次执行回调,对于这种情况就是让子线程上的runloop跑起来. - (void)demoTimer { [NSThread detachNewTh

【iOS开发每日小笔记(九)】在子线程中使用runloop,正确操作NSTimer计时的注意点 三种可选方法

这篇文章是我的[iOS开发每日小笔记]系列中的一片,记录的是今天在开发工作中遇到的,可以用很短的文章或很小的demo演示解释出来的小心得小技巧.它们可能会给用户体验.代码效率得到一些提升,或是之前自己没有接触过的技术,很开心的学到了,放在这里得瑟一下.其实,90%的作用是帮助自己回顾.记忆.复习. 一直想写一篇关于runloop学习有所得的文章,总是没有很好的例子.正巧自己的上线App Store的小游戏<跑酷好基友>(https://itunes.apple.com/us/app/pao-k

在子线程中使用runloop,正确操作NSTimer计时的注意点 三种可选方法

游戏中有一个计时功能.在1.0版本中,使用了简单的在主线程中调用: 1 + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo; 的方法.但是当每0.01秒进行一次repeat操作时,NSTimer是不准的,严重滞后,而改成0.1秒repeat操作,则这种

C#在某个线程上创建的控件不能成为在另一个线程上创建的控件的父级

首先在form1的窗体载入中新建了一个Class1对象并将本身的引用传递进入其构造函数,然后在Class1的构造函数中创建一个线程.该线程所代理的方法事件是本类中的一个add方法.而add方法的内容则是在form1上放一个textbox.然而这个流程你需要注意的有几个问题:1.哪个是主线程?所谓主线程是第一个启动的线程,是从main开始的.form1的这个窗体是由主线程创建的.2.Thread t的线程是什么?t是由主线程创建的,t的操作内容是在由主线程创建的窗体上放一个textbox.也就是说

在指定的CEF线程上执行任务

CEF有几种线程,比如TID_UI.比如TID_RENDER,每种都有特定的含义,具体类别定义在cef_types.h中,摘录如下: typedef enum { // BROWSER PROCESS THREADS -- Only available in the browser process. /// // The main thread in the browser. This will be the same as the main // application thread if C

计算机操作系统学习笔记_2_进程管理 --进程与线程(上)

h3.western { font-family: "Liberation Sans",sans-serif; }h3.cjk { font-family: "微软雅黑"; }h3.ctl { font-family: "AR PL UMing CN"; }h2.western { font-family: "Liberation Sans",sans-serif; font-size: 16pt; }h2.cjk { fon

在C#中子线程如何操作主窗口线程上的控件

在C#中子线程怎样操作主线程中窗口上控件 在C#中,直接在子线程中对窗口上的控件操作是会出现异常,这是因为子线程和运行窗口的线程是不同的空间,因此想要在子线程来操作窗口上的控件.是不可能简单的通过控件对象名来操作,但不是说不能进行操作,微软提供了Invoke的方法.其作用就是让子线程告诉窗口线程来完毕对应的控件操作. 要实现该功能,基本思路例如以下: 把想对还有一线程中的控件实施的操作放到一个函数中,然后使用delegate代理那个函数.而且在那个函数中加入一个推断,用 InvokeRequir

ueditor单独调用上传附件和图片的功能

javascript富文本编辑器使我们添加.编辑网站中的文章更加方便和容易.这些富文本编辑器提供了所见即所得(What You See Is What You Get - WYSIWYG)的功能,可以像编辑word文档一样,方便地编辑网站中文章,常用于内容管理系统和博客系统等. 百度Ueditor富文本就是其中之一,个人觉得虽然体积大点,不兼容移动端外,其他功能都非常强大,特别是里面的多图上传! 当有些个性化页面需求时,难免会对她一些优化,已让她适合自己的内容,比如单独调用上传图片实现类似于以下

在非UI 线程上Show一个含有WebBrowser的Form出现的问题

问题描述: 客户端的Windows程序使用WebMethod从服务器上取得一个系统信息列表.信息列表中有多条Message.当系统消息的时间合要求,使用一个自定义的MessageForm Show出这个系统Message.MessageForm是一个含有WebBrowser的WinForm. Show MessageForm的调用在一个Timer中被执行.当调用ShowMessage的操作时会出现下面的错误. 出错的代码: private void btnTestS_Click(object s