首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >使用-performSelector:与仅仅调用方法

使用-performSelector:与仅仅调用方法
EN

Stack Overflow用户
提问于 2009-09-29 15:01:14
回答 4查看 64.8K关注 0票数 117

我仍然是Objective-C的新手,我想知道下面两个语句之间的区别是什么?

代码语言:javascript
复制
[object performSelector:@selector(doSomething)]; 

[object doSomething];
EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-09-29 15:09:37

基本上,performSelector允许您动态确定在给定对象上调用哪个选择器。换句话说,不需要在运行前确定选择器。

因此,即使它们是等价的:

代码语言:javascript
复制
[anObject aMethod]; 
[anObject performSelector:@selector(aMethod)]; 

第二个表单允许您这样做:

代码语言:javascript
复制
SEL aSelector = findTheAppropriateSelectorForTheCurrentSituation();
[anObject performSelector: aSelector];

在你发送信息之前。

票数 193
EN

Stack Overflow用户

发布于 2014-08-04 05:52:16

对于问题中最基本的例子,

代码语言:javascript
复制
[object doSomething];
[object performSelector:@selector(doSomething)]; 

在将要发生的事情上没有区别。doSomething将由object同步执行。只有"doSomething“是一个非常简单的方法,它不返回任何东西,也不需要任何参数。

是不是有点复杂,比如:

代码语言:javascript
复制
(void)doSomethingWithMyAge:(NSUInteger)age;

事情会变得复杂,因为对象用things做了一些事情:42;

不能再与"performSelector“的任何变体一起调用,因为所有带参数的变体都只接受对象参数。

这里的选择器应该是"doSomethingWithMyAge:“,但任何尝试

代码语言:javascript
复制
[object performSelector:@selector(doSomethingWithMyAge:) withObject:42];  

根本不会编译。传递一个NSNumber:@( 42 )而不是42也没有什么帮助,因为该方法需要一个基本的C类型,而不是一个对象。

此外,还有多达2个参数的performSelector变体,不能再多了。而很多时候,方法有更多的参数。

我发现,尽管performSelector的同步变体:

代码语言:javascript
复制
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;

总是返回一个对象,我也能够返回一个简单的BOOL或NSUInteger,并且它起作用了。

performSelector的两个主要用途之一是动态编写要执行的方法的名称,如前面的答案所述。例如

代码语言:javascript
复制
 SEL method = NSSelectorFromString([NSString stringWithFormat:@"doSomethingWithMy%@:", @"Age");
[object performSelector:method];

另一个用途是向object异步分派一条消息,该消息稍后将在当前runloop上执行。对于这一点,还有其他几种performSelector变体。

代码语言:javascript
复制
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay inModes:(NSArray *)modes;
- (void)performSelector:(SEL)aSelector withObject:(id)anArgument afterDelay:(NSTimeInterval)delay;
- (void)performSelector:(SEL)aSelector target:(id)target argument:(id)arg order:(NSUInteger)order modes:(NSArray *)modes;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg;

(是的,我从几个基础类类别中收集了它们,如NSThread、NSRunLoop和NSObject)

每种变体都有自己的特殊行为,但都有一些共同之处(至少当waitUntilDone设置为NO时是这样)。"performSelector“调用将立即返回,对象的消息只会在一段时间后被放到当前的运行循环中。

由于延迟执行--选择器的方法自然没有返回值可用,因此在所有这些异步变量中都有-(void)返回值。

我希望我以某种方式涵盖了这一点。

票数 17
EN

Stack Overflow用户

发布于 2009-09-29 16:01:43

@乏味杀手说得很对。基本上,当您不知道(并且通常不可能)在编译代码时要调用的方法的名称时,动态生成的选择器很有用。

一个关键的区别是-performSelector:和朋友(包括multi-threaded and delayed variants)有一些限制,因为它们被设计为使用带有0-2个参数的方法。例如,使用6个参数调用-outlineView:toolTipForCell:rect:tableColumn:item:mouseLocation:并返回NSString是非常笨拙的,而且所提供的方法也不支持它。

票数 12
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1493125

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档