zoukankan      html  css  js  c++  java
  • 将NSTimer加入至RunLoop中的两种方法差别

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
    {
        self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
         
        //用NSObject的方法创建一个多线程
        [self performSelectorInBackground:@selector(multiThread) withObject:nil];
         
        self.window.backgroundColor = [UIColor whiteColor];
        [self.window makeKeyAndVisible];
        return YES;
    }
    - (void)multiThread
    {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        if (![NSThread isMainThread]) {
             
            // 第1种方式
            //此种方式创建的timer已经加入至runloop中
    //        [NSTimer scheduledTimerWithTimeInterval:1.0f target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
            //保持线程为活动状态,才干保证定时器运行
    //        [[NSRunLoop currentRunLoop] run];//已经将nstimer加入到NSRunloop中了
             
            //第2种方式
            //此种方式创建的timer没有加入至runloop中
           NSTimer *timer = [NSTimer timerWithTimeInterval:1.0f target:self selector:@selector(timerAction) userInfo:nil repeats:YES];
            //将定时器加入到runloop中
            [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
            [[NSRunLoop currentRunLoop] run];
            NSLog(@"多线程结束");
        }
         [pool release];
    }
     
    - (void)timerAction
    {
        //定时器也是在子线程中运行的
        if (![NSThread isMainThread]) {
            NSLog(@"定时器");
        }
    }








    理解run loop后,才干彻底理解NSTimer的实现原理,也就是说NSTimer实际上依赖run loop实现的。

    先看看NSTimer的两个经常用法:

    + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo; //生成timer但不运行

    + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(id)userInfo repeats:(BOOL)yesOrNo; //生成timer而且纳入当前线程的run loop来运行

    NSRunLoop与timer有关方法为:

    - (void)addTimer:(NSTimer *)timer forMode:(NSString *)mode; //在run loop上注冊timer

    主线程已经有run loop,所以NSTimer一般在主线程上执行都不必再调用addTimer:。但在非主线程上执行必须配置run loop。该线程的main方法演示样例代码例如以下:

    - (void)main

    {

      NSTimer *myTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(timer:) userInfo:nil repeats:YES];

      NSRunLoop *runLoop = [NSRunLoop currentRunLoop];

      [runLoop addTimer:myTimer forMode:NSDefaultRunLoopMode]; //实际上这步是不须要,scheduledTimerWithTimeInterval已经纳入当前线程执行。

    假设使用timerWithTimeInterval则须要

      while (condition)

        [runLoop run];

    }

    实际上这个线程无法退出,由于有timer事件须要处理。[runLoop run]会一直无法返回。

    解决的方法就是设置一个截止时间:

    [runLoop runUntilDate:[NSDate dateWithTimeIntervalSinceNow:10.0]]; //每隔10秒检查下线程循环条件,当然时间值能够依据实际情况来定。

     

    我们通常在主线程中使用NSTimer。有个实际遇到的问题须要注意。当滑动界面时,系统为了更好地处理UI事件和滚动显示,主线程runloop会临时停止处理一些其他事件,这时主线程中执行的NSTimer就会被暂停。解决的方法就是改变NSTimer执行的mode(mode能够看成事件类型)。不使用缺省的NSDefaultRunLoopMode,而是改用NSRunLoopCommonModes,这样主线程就会继续处理NSTimer事件了。详细代码例如以下:

    NSTimer *timer = [NSTimer timerWithTimeInterval:1.0 target:self selector:@selector(timer:) userInfo:nil repeats:YES];

    [[NSRunLoop currentRunLoopaddTimer:timer forMode:NSRunLoopCommonModes];

    大家能够參看博文http://bluevt.org/?

    p=209,加深理解NSTimer和NSRunLoop的关系。


     

    曾经博文中提到延迟调用的方法,事实上就是在当前线程的run loop上注冊timer来实现定时执行的。所以假设是在非主线程上使用,一定要有一个run loop。

    - (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray*)modes;

    - (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;


  • 相关阅读:
    520了,用32做个简单的小程序
    sql使用手册
    大厂Redis高并发场景设计,面试问的都在这!
    如何根据普通ip地址获取当前地理位置
    理解Python闭包,这应该是最好的例子
    520了,用32做个简单的小程序
    适合 C++ 新手学习的开源项目——在 GitHub 学编程
    寄存器(内存访问)01 零基础入门学习汇编语言13
    寄存器(CPU工作原理)07 零基础入门学习汇编语言12
    数组08 零基础入门学习C语言30
  • 原文地址:https://www.cnblogs.com/llguanli/p/7098448.html
Copyright © 2011-2022 走看看