我仍然是一种新的以Objective-C和我不知道什么是以下两个语句之间的区别?
[object performSelector:@selector(doSomething)];
[object doSomething];
我仍然是一种新的以Objective-C和我不知道什么是以下两个语句之间的区别?
[object performSelector:@selector(doSomething)];
[object doSomething];
基本上performSelector允许动态确定哪些选择来调用给定对象上的选择器。 换句话说,选择不需要运行之前确定。
因此,即使这些是相同的:
[anObject aMethod];
[anObject performSelector:@selector(aMethod)];
第二种形式允许你这样做:
SEL aSelector = findTheAppropriateSelectorForTheCurrentSituation();
[anObject performSelector: aSelector];
您之前发送邮件。
对于在这个问题非常基本的例子,
[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)返回在所有这些变体异步值。
我希望我介绍这个莫名其妙...
@ennuikiller是即期。 基本上,动态生成的选择是当你没有(也不可能有可能通常)知道,当你编译代码,你会调用该方法的名称非常有用。
一个关键的区别是, -performSelector:
和朋友(包括多线程和延迟变体 )稍微受限于它们被设计用于与有0-2个参数的方法中使用。 例如,调用-outlineView:toolTipForCell:rect:tableColumn:item:mouseLocation:
有6个参数和返回NSString
是非常笨重,而不是通过所提供的方法支持。
选择器有点像在其他语言中的函数指针。 您可以使用它们,当你不知道你要在运行时调用哪个方法编译的时候做。 此外,像函数指针,它们只是调用封装的动词部分。 如果该方法有参数,你就需要通过他们。
一个NSInvocation
作用也类似,不同之处在于它结合在一起的更多信息。 它不仅包括动词的一部分,它还包括所述目标对象和所述参数。 当你想打电话给特别的参数,而不是现在而是在未来某一特定对象的方法,这非常有用。 你可以建立一个适当的NSInvocation
,后来火了。
还有就是两者之间的另一个细微的差别。
[object doSomething]; // is executed right away
[object performSelector:@selector(doSomething)]; // gets executed at the next runloop
下面是来自苹果文档的摘录