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

本文详细探讨了在Objective-C中如何使用默认模式在当前线程的run loop上延迟执行方法。解析了底层机制,包括定时器配置、消息调度流程及取消机制。

一、文档原文

Description: Invokes a method of the receiver on the current thread using the default mode after a delay.

    This method sets up a timer to perform the aSelectormessage on the current thread’s run loop. The timer is configured to run in the                     default mode (NSDefaultRunLoopMode). When the timer fires, the thread attempts to dequeue the message from the run loop and                           perform the selector. It succeeds if the run loop is running and in the default mode; otherwise, the timer waits until the run loop is in                     the default mode. 

   If you want the message to be dequeued when the run loop is in a mode other than the default mode, use the performSelector:   withObject:afterDelay:inModes: method instead. If you are not sure whether the current thread is the main thread, you can use the    performSelectorOnMainThread:withObject:waitUntilDone: or performSelectorOnMainThread:withObject:waitUntilDone:           modes: method to guarantee that your selector executes on the main thread. To cancel a queued message, use the    cancelPreviousPerformRequestsWithTarget: or cancelPreviousPerformRequestsWithTarget:selector:object:method. 

Parameters:

aSelector:      A selector that identifies the method to invoke. The method should not have a significant return value and should take a single      argument of type id, or no arguments.

anArgument:The argument to pass to the method when it is invoked. Pass nil if the method does not take an argument. 

delay:            The minimum time before which the message is sent. Specifying a delay of 0 does not necessarily cause the selector to be       performed immediately. The selector is still queued on the thread’s run loop and performed as soon as possible.


二、文档解析

1)This method sets up a timer to perform…

     What:此处的timer不是Foundation库中的NSTimer,而是Core Foundation库中的一个结构体:struct __CFRunLoopTimer。

   Why为什么再这里强调一下呢?因为若理解成NSTimer的话,会引起一系列的矛盾。此处不做展开详述,后续再续

     (比如:NSTimer本身时间度量不准确性与aSelector被执行时相对准确性的矛盾、NSTimer没有Enqueue、Dequeue概念与__CFRunLoopTimer有Enqueue、Dequeue概念等


2)The timer is configured to run in the default mode (NSDefaultRunLoopMode).

  What:此处configure是只有底层内部创建timer,不需要上层开发人员参与。

  Why:因为要保证runloop的正常运行逻辑,CFRunloop基本上不允许上层开发参与定制,只允许使用。此处涉及方法为:CFRunLoopAddTimer。

此处不做展开详述,后续再续

What:此处NSDefaultRunLoopMode,因此在使用时不要联合使用涉及Mode的方法,除非你特别清除Mode各种情况,即便是main thread也是一样。(比如:GCD、NSObject delay perform中涉及mode的方法)

    Why:因为Mode会涉及到runloop的mode切换(平行切换、嵌套切换)、defaultMode与CommonMode的区别联系。此处不做展开详述,后续再续


3)When the timer fires, the thread attempts to dequeue the message from the run loop and                           perform the selector

   What:本质上是__CFRunLoopTimer从_timers_timers属于__CFRunLoopMode的结构体成员)中被dequeue,

         然后调用_callout(_callout是__CFRunLoopTimer的结构体成员),进而实现调用Selector。

   Why:上述逻辑都是在runloop内部实现的,对外是不可见。此处不做展开详述,后续再续


4)The method should not have a significant return value……

   Why:who tell me why????


5)Specifying a delay of 0 does not necessarily cause the selector to be performed immediately

  What:由3)可知只有__CFRunLoopTimer被dequeue时,Selector才能得到被执行。那么__CFRunLoopTimer是何时被dequeue的呢?

        总所周知:runloop是个运行环,假设执行环路线逻辑是:A-->B-->C-->D-->A,B点是__CFRunLoopTimer被dequeue

        如果CFRunLoopAddTimer在B点之前执行,则B会在本runloop周期内执行。

        如果CFRunLoopAddTimer在B点之后执行,则B会在下一个runloop周期内执行。此处不做展开详述,后续再续

        

因此也就能理解:

       The minimum time before which the message is sent. 

       The selector is still queued on the thread’s run loop and performed as soon as possible.

   

 

   

   

       




评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值