我仍然是Objective-C的新手,我想知道下面两个语句之间的区别是什么?
[object performSelector:@selector(doSomething)];
[object doSomething];
发布于 2009-09-29 15:09:37
基本上,performSelector允许您动态确定在给定对象上调用哪个选择器。换句话说,不需要在运行前确定选择器。
因此,即使它们是等价的:
[anObject aMethod];
[anObject performSelector:@selector(aMethod)];
第二个表单允许您这样做:
SEL aSelector = findTheAppropriateSelectorForTheCurrentSituation();
[anObject performSelector: aSelector];
在你发送信息之前。
发布于 2014-08-04 05:52:16
对于问题中最基本的例子,
[object doSomething];
[object performSelector:@selector(doSomething)];
在将要发生的事情上没有区别。doSomething将由object同步执行。只有"doSomething“是一个非常简单的方法,它不返回任何东西,也不需要任何参数。
是不是有点复杂,比如:
(void)doSomethingWithMyAge:(NSUInteger)age;
事情会变得复杂,因为对象用things做了一些事情:42;
不能再与"performSelector“的任何变体一起调用,因为所有带参数的变体都只接受对象参数。
这里的选择器应该是"doSomethingWithMyAge:“,但任何尝试
[object performSelector:@selector(doSomethingWithMyAge:) withObject:42];
根本不会编译。传递一个NSNumber:@( 42 )而不是42也没有什么帮助,因为该方法需要一个基本的C类型,而不是一个对象。
此外,还有多达2个参数的performSelector变体,不能再多了。而很多时候,方法有更多的参数。
我发现,尽管performSelector的同步变体:
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;
总是返回一个对象,我也能够返回一个简单的BOOL或NSUInteger,并且它起作用了。
performSelector的两个主要用途之一是动态编写要执行的方法的名称,如前面的答案所述。例如
SEL method = NSSelectorFromString([NSString stringWithFormat:@"doSomethingWithMy%@:", @"Age");
[object performSelector:method];
另一个用途是向object异步分派一条消息,该消息稍后将在当前runloop上执行。对于这一点,还有其他几种performSelector变体。
- (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)返回值。
我希望我以某种方式涵盖了这一点。
发布于 2009-09-29 16:01:43
@乏味杀手说得很对。基本上,当您不知道(并且通常不可能)在编译代码时要调用的方法的名称时,动态生成的选择器很有用。
一个关键的区别是-performSelector:
和朋友(包括multi-threaded and delayed variants)有一些限制,因为它们被设计为使用带有0-2个参数的方法。例如,使用6个参数调用-outlineView:toolTipForCell:rect:tableColumn:item:mouseLocation:
并返回NSString
是非常笨拙的,而且所提供的方法也不支持它。
https://stackoverflow.com/questions/1493125
复制相似问题