在 Objective-c 中,performSelector 是内联执行的还是作为不同事件发布执行的?

In Objective-c is performSelector executed inline or is it posted for execution as a different event?

这很重要的原因有很多。如果您没有使用 ARC,这里有一个简单的例子。

[instance performSelector:selector withObject:objectA];
[objectA release];    // Did the selector actually finish executing
                      // in the line above so everyone's done with objectA
                      // or did the selector merely get scheduled in the line
                      // above, and is yet to execute, so objectA had better
                      // not be released yet?

我做了一些研究,上下文线索似乎指向选择器是内联完成的。但是我在任何地方都没有看到任何明确的声明,声明它是内联执行的。

performSelector:withObject: 同步执行(阻塞直到方法完成)。

使用performSelector:withObject:afterDelay:在主线程上异步执行方法(return立即执行,稍后执行)。

使用performSelectorInBackground:withObject:在后台线程上异步执行方法(return立即在不同的线程上执行)。

注意: performSelector 和它的朋友应该避免,因为如果你在方法签名不兼容的方法上使用它们是未定义的行为。

The aSelector argument should identify a method that takes no arguments. For methods that return anything other than an object, use NSInvocation.

https://developer.apple.com/library/mac/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/index.html#//apple_ref/occ/intfm/NSObject/performSelector:

Did the selector actually finish executing in the line above so everyone's done with objectA or did the selector merely get scheduled in the line above, and is yet to execute, so objectA had better not be released yet?

没关系,为了内存管理的目的。 Cocoa 中的内存管理是 local -- 你只需要关心你的函数做了什么;您不需要知道,也不应该关心其他功能在内部做什么,以正确管理内存(忽略保留周期)。只要您完成了拥有的引用,就应该释放它。其他人用完了对你来说没关系。

这是因为,根据Cocoa内存管理规则,任何需要存储它以便在函数调用之外使用的函数都需要保留它并在完成时释放它(因为函数不能假设否则该对象存在于调用范围之外)。任何异步使用参数的函数(例如 performSelector:withObject:afterDelay: 等)确实会保留对象并在完成后释放它。

或者,这样想:ARC 是如何工作的? ARC 如何知道一个函数是同步还是异步使用它的参数?它没有。没有注释告诉编译器函数是同步使用还是异步使用。然而 ARC 做对了。这意味着您也可以,而无需知道该函数是同步还是异步使用其参数。