zoukankan      html  css  js  c++  java
  • NSTimer拓展

    定时器(NSTimer)在我们日常开发中是一个非常有用的系统函数,开发者可以在指定的时间,或延迟执行某些任务,也可以设定间隔时间重复执行任务。

    //iOS提供的Timer构造方法
    + (NSTimer *)timerWithTimeInterval:(NSTimeInterval)ti 
                                target:(id)aTarget 
                                selector:(SEL)aSelector 
                                userInfo:(nullable id)userInfo 
                                repeats:(BOOL)yesOrNo;
    
    //对应的析构方法
    - (void)invalidate;
    

    在使用Timer时,timer会保留target对象,直到自身失效(invalid)后再释放该对象。对于一次性的timer在触发后就会失效,然后重复性的需要手动invalidate,所以alloc和dealloc最好成对出现,才可以防止引起retain,从而造成内存的泄露。
    

    这里通过扩展NSTimer,使用block来消除retain-cycle(如果忘记invalidate,也没有关系了)。

    //NSTimer+BlockSupport.h
    #import <Foundation/Foundation.h>
    
    @interface NSTimer(BlockSupport)
    
    + (NSTimer *)law_scheduleTimerWithTimeInterval:(NSTimeInterval)interval
                                           repeats:(BOOL)repeats
                                             block:(void(^)(NSTimer *timer))block;
    
    @end
    
    
    //NSTimer+BlockSupport.m
    #import "NSTimer+BlockSupport.h"
    
    @implementation NSTimer(BlockSupport)
    
    //将block作为userInfo传递进去,并copy到堆栈中,以防止执行block时失效
    //这时target是NSTimer本身,NSTimer是一个单例对象,尽管存在ratain cycle,但是没有关系
    + (NSTimer *)law_scheduleTimerWithTimeInterval:(NSTimeInterval)interval
                                         repeats:(BOOL)repeats
                                           block:(void(^)(NSTimer *timer))block {
        return [self scheduledTimerWithTimeInterval:interval
                                             target:self
                                           selector:@selector(law_blockInvoke:)
                                           userInfo:[block copy]
                                            repeats:repeats];
    }
    
    + (void)law_blockInvoke:(NSTimer *)timer {
        void (^block)(NSTimer *timer) = timer.userInfo;
        if (block) {
            block(timer);
        }
    }
    
    @end
    

    使用

    - (void)startTimer {
        __weak __typeof(self)weakSelf = self;
        [NSTimer law_scheduleTimerWithTimeInterval:5.0 repeats:YES block:^(NSTimer *timer) {
            __strong __typeof(weakSelf)strongSelf = weakSelf;
            [strongSelf doSomething];
        }];
    }
    
    - (void)doSomething {
        //do something
    }
    

    好消息是,iOS10之后系统已经支持该方法了。不过目前iOS应用大都还需要支持iOS8.0+,所以该拓展还是有那么些作用。

  • 相关阅读:
    Jdk1.8 HashMap源码分析
    瘦身部署应用
    Redis 创建和使用集群(yum方式安装低版本)
    Redis 创建和使用集群
    记录一下
    Oracle 开发人员权限控制
    Linux 免密登录远程服务器及执行相关命令
    Oracle 连接表空间并执行SQL文件
    MySQL 8.0.13安装教程(windows 64位) (转)
    scrapy中Selector的使用
  • 原文地址:https://www.cnblogs.com/horo/p/6854815.html
Copyright © 2011-2022 走看看