zoukankan      html  css  js  c++  java
  • Object-C定时器,封装GCD定时器的必要性!!! (一)

    实际项目开发中经常会遇到延迟某件任务的执行,或者让某件任务周期性的执行。然后也会在某些时候需要取消掉之前延迟执行的任务。

    iOS中延迟操作有三种解决方案:

    1、NSObject的方法:(对象方法)

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

    2、使用NSTimer的方法:

    + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));

    //需要手动添加到运行循环

    ------------------------------------------------------------------------------

    + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)ti target:(id)aTarget selector:(SEL)aSelector userInfo:(nullable id)userInfo repeats:(BOOL)yesOrNo;

    //创建后会默认添加到NSDefaultRunLoopMode中,这个方法创建的定时器不会自动销毁,需要手动销毁,会被self强引用着,不特殊处理就会产生强引用循环,造成内存泄露. 一定不要使用这个方法,请使用下面的方法替代这个方法.

    ------------------------------------------------------------------------------

    + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));

    //创建后会默认添加到NSDefaultRunLoopMode中,添加到block中,系统回自己处理(不会强引用),系统会调用dealloc方法我们在此处销毁timer即可

    ------------------------------------------------------------------------------

     

     

    模式:以下两种模式同一时刻只能是一种模式

    NSDefaultRunLoopMode(默认模式)

    UITrackingRunLoopMode(如果控制器的view上面有滚动视图,但手指拖拽滚动视图的时候,就会进入该模式.一般不会将定时器加入到这个模式中,如果想在滚动视图的时候,定时器同样起效一般会加入到下面的模式) 

    ---------------------------------------------------------------------------------------

    NSRunLoopCommonModes:上面两个模式都能运行

     

     

    3、使用GCD的方法:

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{

         //延迟执行的代码 

      

    });

     

    一般情况下,我们选择使用GCD的dispatch_after。

    因为如果不用GCD,需要注意以下三个细节:

    1.必须保证有一个活跃的runloop。

    当一个应用启动时,系统会开启一个主线程,并且把主线程跑起来,并且主线程的runloop是不会停止的。所以,当这两个方法在主线程可以被正常调用。但实际编程中大部分逻辑处理是放在子线程中执行的。而子线程的runloop是默认关闭的。如果不手动激活runloop,performSelector和scheduledTimerWithTimeInterval的调用将是无效的。

    2.NSTimer、performSelector的创建与撤销必须在同一个线程操作。

    3.内存有潜在泄露的风险 

    4.NSTimer相对于Dispatch定时器来说不准时.

    + (NSTimer *)scheduledTimerWithTimeInterval:(NSTimeInterval)interval repeats:(BOOL)repeats block:(void (^)(NSTimer *timer))block API_AVAILABLE(macosx(10.12), ios(10.0), watchos(3.0), tvos(10.0));

    //当然使用这个方法,不会产生强引用循环(系统已经帮我们处理了),我们只需要在对应的dealloc方法中销毁定时器就OK了

    但是dispatch_after有个致命的弱点:dispatch_after一旦执行后,就不能撤销了。

    其实GCD也有timer的功能。

    // 1.获得队列

     dispatch_queue_t queue = dispatch_get_global_queue(0, 0);

      //dispatch_queue_t queue = dispatch_get_main_queue();

     

     // 2.创建一个定时器(dispatch_source_t本质还是个OC对象

     self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);

     

     // 3.设置timer执行的事件

    dispatch_time_t start = dispatch_time(DISPATCH_TIME_NOW,1.0 * NSEC_PER_SEC);//1.0秒之后开始执行

     uint64_t interval = (uint64_t)(2.0 * NSEC_PER_SEC);//每隔2.0秒执行一次

     dispatch_source_set_timer(self.timer, start, interval, 0);

     

     //4. 设置回调

     dispatch_source_set_event_handler(self.timer, ^{

          // 取消timer 或者做其他事情

          dispatch_cancel(self.timer);

          self.timer = nil;

     });

     

     //5.启动定时器/激活timer

     dispatch_resume(self.timer);

     

    这样我们就规避了NSTimer的三个缺陷。

    我靠... 这也太复杂了!!! 而且还没有repeats选项

    我们能不能像NSTimer那样使用呢?答案:当然有了!!!

    没错! 我们将重复的代码封装起来,开放几个供外界调用的参数!

    有了思路写代码就很简单了!

     

     

    更多内容--> 博客导航 每周一篇哟!!!

     

     

    有任何关于iOS开发的问题!欢迎下方留言!!!或者邮件lieryangios@126.com 虽然我不一定能够解答出来,但是我会请教iOS开发高手!!!解答您的问题!!!

     

     

     

    详细设计请看下一篇: Object-C定时器,封装GCD定时器的必要性!!! (二)

     

     

  • 相关阅读:
    路西法效应 和 数学公式输入
    coursera python
    epub java
    How do remove the CD / DVD install as a source for apt-get packages when installing new features?
    vmware player 去除full screen的bar
    Install VMware tools on Ubuntu 20.04 Focal Fossa Linux
    java poi for word
    handwriting ocr
    总结5.22PHP网络与变量
    总结5.12js代表练习题
  • 原文地址:https://www.cnblogs.com/CoderEYLee/p/Object-C-0004.html
Copyright © 2011-2022 走看看