performSelector
是什么?创建新的NSThread
和使用performSelector
方法有什么区别?
它是如何工作的,我们应该在哪里使用它?
performSelector
是什么?创建新的NSThread
和使用performSelector
方法有什么区别?
它是如何工作的,我们应该在哪里使用它?
这些方法的作用都是一样的,即使得anObject
对象上的doStuff
方法在当前线程上同步执行:
// 1
[anObject doStuff];
// 2
[anObject performSelector:@selector(doStuff)];
// 3
objc_msgSend(anObject, @selector(doStuff));
// 4
IMP imp = [anObject methodForSelector:@selector(doStuff)];
imp(anObject, @selector(doStuff));
anObject
类别未知,则使用此方法。通常会首先使用 -[NSObject respondsToSelector:]
方法查询对象是否包含该方法。IMP
(实现),然后直接调用它。如果在紧密循环中使用,有时比方法1更快。但请记住,“过早优化是万恶之源”。你需要理解的是,在Objective-C中,方法比类/接口更重要。通常情况下,您不需要查询对象是否属于特定类别或符合任何协议,这是编译器应该关注的问题。在运行时,您需要查询特定的方法。
简而言之:重要的不是你是什么,而是你能做什么。
方便起见,NSObject
还有几个异步的姐妹方法,其中最重要的是:
performSelector:withObject:afterDelay:
- 以延迟的方式在当前线程上执行该方法。performSelectorInBackground:withObject:
- 在新的后台线程上执行该方法。performSelectorOnMainThread:withObject:waitUntilDone:
- 在主线程上执行该方法。performSelector:onThread:withObject:waitUntilDone:
- 在任何线程上执行该方法。所有异步执行的方法都依赖于NSRunLoop
。除非您自己创建线程,否则无需担心这一点。如果确实要创建线程,则还需要运行新线程的运行循环。现在暂时跳过这些。
id foo; if ([foo respondsToSelector:@selector(bar)]) [foo bar];
当您在编译时不知道要调用的选择器时(例如从另一个对象发送过来的,或者是用户可选的等),您需要使用performSelector:
。 - Daniel Dickison