- (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.

   

 

   

   

       




你提供的代码片段是 Objective-C 中常见的写法,主要用于在 `self` 可能被释放的情况下安全地引用它,并延迟调用某个方法。我们来逐行解释这段代码的含义以及它的作用。 ### 代码解释: ```objective-c __weak typeof(self) weakSelf = self; ``` - 这行代码创建了一个对 `self` 的弱引用(weak reference),防止在 block 或异步操作中造成循环引用(retain cycle)。 - `__weak` 是 Objective-C 中的修饰符,表示这个指针不会增加对象的引用计数。 - `typeof(self)` 是 GNU C 的扩展,用于获取 `self` 的类型,这样 `weakSelf` 就会是和 `self` 相同类型的指针。 - 通常这行代码用于在 block 内部使用 `weakSelf` 来避免强引用循环。 ```objective-c [self performSelector:@selector(dismissalert:) withObject:@"firstParameter" afterDelay:1.0]; ``` - 这行代码使用了 NSObject 的 `performSelector:withObject:afterDelay:` 方法,表示在 1 秒后调用 `self` 的 `dismissalert:` 方法。 - `@selector(dismissalert:)` 表示方法名是 `dismissalert:`,并且它接受一个参数。 - `withObject:@"firstParameter"` 表示传给该方法的参数是字符串 `@"firstParameter"`。 - 如果在这个 1 秒延迟期间 `self` 被释放,那么这个方法将不会被执行。 ### 完整示例代码: ```objective-c - (void)showAlert { __weak typeof(self) weakSelf = self; [weakSelf performSelector:@selector(dismissalert:) withObject:@"firstParameter" afterDelay:1.0]; } - (void)dismissalert:(NSString *)message { NSLog(@"Dismiss alert with message: %@", message); } ``` ### 注意事项: 虽然 `performSelector:withObject:afterDelay:` 会在对象被释放后自动取消调用,但如果你是在 block 中使用 `self`,仍然建议使用 `weakSelf` 来避免循环引用。 例如: ```objective-c dispatch_async(dispatch_get_main_queue(), ^{ [weakSelf dismissalert:@"from block"]; }); ``` ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值