使用-performSelector:对只是调用该方法(Using -performSelector

2019-07-20 01:45发布

我仍然是一种新的以Objective-C和我不知道什么是以下两个语句之间的区别?

[object performSelector:@selector(doSomething)]; 

[object doSomething];

Answer 1:

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

因此,即使这些是相同的:

[anObject aMethod]; 
[anObject performSelector:@selector(aMethod)]; 

第二种形式允许你这样做:

SEL aSelector = findTheAppropriateSelectorForTheCurrentSituation();
[anObject performSelector: aSelector];

您之前发送邮件。



Answer 2:

对于在这个问题非常基本的例子,

[object doSomething];
[object performSelector:@selector(doSomething)]; 

有什么事情发生没有什么区别。 doSomething的将由对象同步地执行。 只有“DoSomething的”是一个非常简单的方法,不返回任何东西,不需要任何参数。

是它的东西更复杂一点,比如:

(void)doSomethingWithMyAge:(NSUInteger)age;

事情会变得复杂,因为[对象doSomethingWithMyAge:42]。

再也不能用“performSelector”的任何变种,叫,因为参数所有变体只接受对象参数。

这里的选择将是“doSomethingWithMyAge:”但任何企图

[object performSelector:@selector(doSomethingWithMyAge:) withObject:42];  

根本不会编译。 通过一个NSNumber:@(42),而不是42,就没有帮助的,因为方法需要一个基本的C型 - 不是对象。

此外,还有performSelector变种多达2个参数,仅此而已。 虽然方法很多时候有更多的参数。

我发现,虽然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];

其他用途,是异步分派消息对象,这将稍后在当前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”调用将立即返回,并寄语对象将只在一段时间后提上当前runloop。

因为延迟执行的 - 天然无返回值是可利用的形式的选择的方法中,因此 - (void)返回在所有这些变体异步值。

我希望我介绍这个莫名其妙...



Answer 3:

@ennuikiller是即期。 基本上,动态生成的选择是当你没有(也不可能有可能通常)知道,当你编译代码,你会调用该方法的名称非常有用。

一个关键的区别是, -performSelector:和朋友(包括多线程和延迟变体 )稍微受限于它们被设计用于与有0-2个参数的方法中使用。 例如,调用-outlineView:toolTipForCell:rect:tableColumn:item:mouseLocation:有6个参数和返回NSString是非常笨重,而不是通过所提供的方法支持。



Answer 4:

选择器有点像在其他语言中的函数指针。 您可以使用它们,当你不知道你要在运行时调用哪个方法编译的时候做。 此外,像函数指针,它们只是调用封装的动词部分。 如果该方法有参数,你就需要通过他们。

一个NSInvocation作用也类似,不同之处在于它结合在一起的更多信息。 它不仅包括动词的一部分,它还包括所述目标对象和所述参数。 当你想打电话给特别的参数,而不是现在而是在未来某一特定对象的方法,这非常有用。 你可以建立一个适当的NSInvocation ,后来火了。



Answer 5:

还有就是两者之间的另一个细微的差别。

    [object doSomething]; // is executed right away

    [object performSelector:@selector(doSomething)]; // gets executed at the next runloop

下面是来自苹果文档的摘录



文章来源: Using -performSelector: vs. just calling the method