MSWeakTimer机制解析

作者: Arnold134777 | 来源:发表于2016-03-26 21:43 被阅读1872次

MSWeakTimer地址:https://github.com/mindsnacks/MSWeakTimer

基本介绍

线程安全的MSWeakTimer是NSTimer的替代品,最基本的特点是它不会 retain target 以及支持GCD queues。

问题的提出

关于 NSTimer 中 target 的生命周期问题,当 repeat 为 YES 时NSTimer 会 retains 它的 target,那么target的生命周期就成了问题,完全的交给了这个timer,只有当timer 调用invalidate后 dealloc 才有机会发生。

另一个问题是GCD,在苹果的官方文档中说的很清楚:

Special Considerations

You must send this message from the thread on which the timer was installed. If you send this message from another thread, the input source associated with the timer may not be removed from its run loop, which could prevent the thread from exiting properly.

invalidate必须由安装这个timer的线程发起,否则这个timer有可能不会从run loop中移除。这种情况会发生的一个情况就是:当这个线程是由 GCD 管理的。这是因为 NSTimer 依赖于当前线程的run loop, 而GCD完全是另外一回事,它不能确保timer的阻塞和invalidate是由同一个线程发起的,run loop和queue将会交织在一起,世界就乱了...

而MSWeakTimer完全就不是用run loop实现的,所以就不用考虑那么多了,它可以与GCD和谐共存,被任意线程 install 和 invalidate。

源码分析
(1)初始化

if ((self = [super init]))
    {
        self.timeInterval = timeInterval;
        self.target = target;
        self.selector = selector;
        self.userInfo = userInfo;
        self.repeats = repeats;

        NSString *privateQueueName = [NSString stringWithFormat:@"com.mindsnacks.msweaktimer.%p", self];
 // 1.创建串行队列
 // Dispatch queues created with the DISPATCH_QUEUE_SERIAL or a NULLattribute
 // invoke blocks serially in FIFO order.
        self.privateSerialQueue = dispatch_queue_create([privateQueueName cStringUsingEncoding:NSASCIIStringEncoding], DISPATCH_QUEUE_SERIAL);
        dispatch_set_target_queue(self.privateSerialQueue, dispatchQueue);
 // 2.dispatch_source 定时器
        self.timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER,
                                            0,
                                            0,
                                            self.privateSerialQueue);
    }

(2)设置定时器的触发时间

dispatch_source_set_timer(self.timer,
                              dispatch_time(DISPATCH_TIME_NOW, intervalInNanoseconds),
                              (uint64_t)intervalInNanoseconds,
                              toleranceInNanoseconds
                              );

(3)设置定时器触发的事件

 __weak MSWeakTimer *weakSelf = self;

    dispatch_source_set_event_handler(self.timer, ^{
        [weakSelf timerFired];
    });

    dispatch_resume(self.timer);

(4)具体event

 if (OSAtomicAnd32OrigBarrier(1, &_timerFlags.timerIsInvalidated)) // 原子操作
    {
        return;
    }

    // We're not worried about this warning because the selector we're calling doesn't return a +1 object.
    #pragma clang diagnostic push
    #pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        [self.target performSelector:self.selector withObject:self];
    #pragma clang diagnostic pop

    if (!self.repeats)
    {
        [self invalidate];
    }

(5)释放

- (void)invalidate
{
    // We check with an atomic operation if it has already been invalidated. Ideally we would synchronize this on the private queue,
    // but since we can't know the context from which this method will be called, dispatch_sync might cause a deadlock.
    if (!OSAtomicTestAndSetBarrier(7, &_timerFlags.timerIsInvalidated))
    {
        dispatch_source_t timer = self.timer;
        dispatch_async(self.privateSerialQueue, ^{
            dispatch_source_cancel(timer);
            ms_release_gcd_object(timer);
        });
    }
}

附:
OSAtomicAnd32OrigBarrier : 用于原子操作的判断,出于线程安全考虑
OSAtomic原子操作:http://southpeak.github.io/blog/2014/10/17/osatomicyuan-zi-cao-zuo/
GCD dispatch_source:http://www.cnblogs.com/sunfrog/p/3308766.html

相关文章

  • MSWeakTimer机制解析

    MSWeakTimer地址:https://github.com/mindsnacks/MSWeakTimer 基...

  • MSWeakTimer

    MSWeakTimer 使用线程安全的 MSWeakTimer ,它不会对目标进行retain操作,避免循环引用h...

  • 摩拜-APP 使用的lib

    MSWeakTimer:代替 NSTime NSTimer 工作原理: 官方解释是“A timer provide...

  • 08.Objective-C 消息机制

    问题 消息机制的三个阶段 1.消息机制发送消息阶段-消息发送2.消息机制动态方法解析阶段 -动态解析3.消息机制消...

  • JavaScript的预解析

    在JavaScript中有一种机制就是:“预解析机制” 简单来说就是在解析过程中会先将函数声明和变量声明提前解析函...

  • Android事件分发机制

    转发一份写的不错的博客[Android事件分发机制解析Android事件分发机制解析 - 简书 (jianshu....

  • Android事件分发机制完全解析

    Android事件分发机制完全解析,带你从源码的角度彻底理解(上)Android事件分发机制完全解析,带你从源码的...

  • 深入解析JavaScript解析机制与闭包原理实例

    篇文章主要介绍了JavaScript解析机制与闭包原理,结合实例形式详细分析了javascript解析机制相关概念...

  • JavaScript解析机制与闭包原理实例详解

    本文实例讲述了JavaScript解析机制与闭包原理。分享给大家供大家参考,具体如下: js解析机制: js代码解...

  • iOS超级签名

    摘抄自:超级签名-原理/机制/技术细节-完全解析蒲公英:超级签名 超级签名-原理/机制/技术细节-完全解析 随着苹...

网友评论

    本文标题:MSWeakTimer机制解析

    本文链接:https://www.haomeiwen.com/subject/wdwdlttx.html