使用[self method]还是@selector(method)?

10

有人能启发我下面这两个陈述的区别吗。

[self playButtonSound];

AND:(翻译为中文)
[self performSelector:@selector(playButtonSound)];

我只是在询问,因为我有一些旧代码使用了 @selector,现在我有了更多的知识,我不明白为什么我没有使用 [self playButtonSound],它们似乎在这里所写的都是相同的。
gary

1
Van:为什么你删除了,这不是有帮助的吗?它们肯定会做同样的事情。一个小区别是第一个示例将发送一条消息playButtonSound;而第二个将发送两条消息,首先是performSelector:,然后发送playButtonSound。我总是会选择第一个选项,除非你没有选择余地,即使只是为了可读性。 - fuzzygoat
2个回答

11

[self playButtonSound];performSelector: 都可以实现同样的功能,但在Objective-C中调用方法时,[self playButtonSound]; 是更常见的方式。然而,使用performSelector:可以允许你在运行时调用一个方法。

根据NSObject Protocol Reference:

  

performSelector :方法等价于直接向接收者发送 aSelector 消息。例如,以下所有三个消息都执行相同的操作:

id myClone = [anObject copy];
id myClone = [anObject performSelector:@selector(copy)];
id myClone = [anObject performSelector:sel_getUid("copy")];

然而,performSelector: 方法允许您发送在运行时才确定的消息。一个可变选择器可以作为参数传递:

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

6
[self playButtonSound]; 

在这里编译器将会检查你的对象是否响应-playButtonSound消息,如果没有响应则会给出警告。

[self performSelector:@selector(playButtonSound)];

这样调用-playButtonSound,您将不会收到编译器警告。但是,您可以动态地检查对象是否响应给定的选择器 - 因此,您可以安全地尝试在对象上调用任意选择器而不指定其类型并且不会收到编译器警告(例如,在调用对象委托中的可选方法时可能很有用):

if ([self respondsToSelector:@selector(playButtonSound)])
  [self performSelector:@selector(playButtonSound)];

在这行代码 if ([self respondsToSelector:@selector(playButtonSound)] 中,有一个缺少的括号 — 应该是 if ([self respondsToSelector:@selector(playButtonSound)]) - Steve Harrison
2
实际上,您可以通过在构建设置中的其他警告标志字段中添加-Wundeclared-selector来使编译器在未声明的选择器处发出警告。我发现这非常有帮助。 - Brad Larson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接