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

在Objective-c中,performSelector是内联执行的,还是作为不同的事件发布执行?,objective-c,selector,Objective C,Selector,这一点很重要,原因有很多。这里有一个简单的例子,如果你没有使用ARC [instance performSelector:selector withObject:objectA]; [objectA release]; // Did the selector actually finish executing // in the line above so everyone's done with objectA

这一点很重要,原因有很多。这里有一个简单的例子,如果你没有使用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:
在主线程上异步执行方法(立即返回,稍后执行)

使用
performSelectorInBackground:withObject:
在后台线程上异步执行方法(立即返回并在不同线程上执行)

注:
performSelector
及其朋友应该避免使用,因为如果您在具有不兼容方法签名的方法上使用它们,则这是未定义的行为

aSelector参数应该标识一个不带参数的方法。对于返回对象以外的任何内容的方法,请使用NSInvocation

:

选择器是否真的在上面的行中完成了执行 每个人都使用objectA了,还是选择器只是被安排好了 在上面的行中,并且尚未执行,因此objectA最好不要 释放了吗

出于内存管理的目的,这无关紧要。Cocoa中的内存管理是本地的——您只需要关心函数的功能;为了正确管理内存(忽略保留周期),您不需要知道,也不应该关心其他函数在内部做了什么。只要你完成了自己的引用,你就应该释放它。如果其他人已经处理好了,这对你来说并不重要

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


或者,可以这样想:ARC是如何工作的?ARC如何知道函数是同步使用参数还是异步使用参数?没有。没有注释告诉编译器函数是同步使用还是异步使用。然而ARC做得很正确。这意味着您也可以这样做,而不知道函数是同步还是异步使用其参数。

@JoshCaswell这并不是真的不赞成(我已经更新了措辞),但正如文档所说,
NSInvocation
应该在大多数时间使用。使用
performSelector
可以轻松添加难以捕获的bug。(例如,将方法签名从return
NSNumber
更改为
double
)我不想在1中问2个问题,但我也看到很多关于选择器不能返回原语等的闲话。但我找不到任何明确的语句说“所有选择器必须返回NSObject*”,事实上我所有的选择器都是-(void)myFunction。它们是有效的,但从技术上讲,我所做的是非法的吗?@JoeC是的,这是未定义的行为。如果您接受return参数并对其进行处理,您的应用程序可能会崩溃。(可能取决于拱门/平台/版本)