【发布时间】:2010-11-30 12:43:47
【问题描述】:
performSelector 是做什么的?创建新的NSThread 和performSelector 方法有什么区别?
它是如何工作的,我们应该在哪里使用它?
【问题讨论】:
标签: objective-c cocoa cocoa-touch cocoa-design-patterns
performSelector 是做什么的?创建新的NSThread 和performSelector 方法有什么区别?
它是如何工作的,我们应该在哪里使用它?
【问题讨论】:
标签: objective-c cocoa cocoa-touch cocoa-design-patterns
所有这些都执行相同的任务,即使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(implementation),然后直接调用。如果在紧密循环中使用,有时可以比 1. 快。只要记住; 过早的优化是邪恶的。您需要掌握的是,在 Objective-C 中,方法比类/接口更重要。通常你不会查询一个对象是否属于一个特定的类,或者是否符合任何协议,这是编译器抱怨的。在运行时,您改为查询特定方法。
简而言之:重要的是你能做什么。
为方便起见,NSObject 也有几个兄弟姐妹 performSelector 是异步的。最值得注意的是:
performSelector:withObject:afterDelay: - 延迟后在当前线程上执行方法。performSelectorInBackground:withObject: - 在新的后台线程上执行该方法。performSelectorOnMainThread:withObject:waitUntilDone: - 在主线程上执行方法。performSelector:onThread:withObject:waitUntilDone: - 在任何线程上执行该方法。异步执行器都依赖NSRunLoop 来运行。这不是你需要担心的事情,除非你自己产生一个线程。如果你这样做了,那么你还需要运行新线程运行循环。暂时跳过它。
【讨论】:
id foo; if ([foo respondsToSelector:@selector(bar)]) [foo bar]; 当你确实需要 performSelector: 是如果你不知道要调用的选择器编译时(例如,它是从不同的对象发送的,或者它是用户可选择的,等等)。
methods are more important than classes/interfaces 的评论很有见地,并解释了Objective-C 和其他OOP 环境之间的关键区别。谢谢。
【讨论】: