ChatGPT解决这个技术问题 Extra ChatGPT

方法和选择器有什么区别?

Objective-C 中的方法、选择器和消息有什么区别?


D
Dave DeLong

这是一个很好的问题。

Selector - Selector 是方法的名称。您对这些选择器非常熟悉:alloc、init、release、dictionaryWithObjectsAndKeys:、setObject:forKey: 等。请注意,冒号是选择器的一部分;这就是我们如何确定此方法需要参数的方式。此外(尽管非常罕见),您可以使用这样的选择器:doFoo:::。这是一个接受三个参数的方法,您可以像 [someObject doFoo:arg1 :arg2 :arg3] 一样调用它。选择器组件的每个部分之前不要求有字母。正如我所说,这非常罕见,您不会发现它在 Cocoa 框架中使用。您可以直接在 Cocoa 中使用选择器。它们的类型为 SEL:SEL aSelector = @selector(doSomething:) 或 SEL aSelector = NSSelectorFromString(@"doSomething:");

消息 - 消息是一个选择器和您发送的参数。如果我说 [dictionary setObject:obj forKey:key],那么“消息”就是选择器 setObject:forKey: 加上参数 obj 和 key。消息可以封装在 NSInvocation 对象中以供以后调用。消息被发送到接收者。 (即“接收”消息的对象)。

方法 - 方法是选择器和实现(以及随附的元数据)的组合。 “实现”是实际的代码块;它是一个函数指针(一个 IMP)。可以使用 Method 结构(可从运行时检索)在内部检索实际方法。

您没有要求的其他一些相关事情:

方法签名 - 方法签名表示方法返回和接受的数据类型。它们可以在运行时通过 NSMethodSignature 和(在某些情况下)原始 char* 来表示。

实现 - 方法的实际可执行代码。它在运行时的类型是一个 IMP,它实际上只是一个函数指针。 iOS 4.3 包含将块转换为 IMP 的新功能。这真的很酷。

要实现的有趣的事情之一是方法(选择器)的名称与方法(IMP)的实现不同。这意味着如果您有胆量,您可以交换它们。您还可以在运行时添加和删除方法,因为您所做的只是编辑哈希表中的条目:键是选择器,值是方法的 IMP。这使您可以做一些非常疯狂和迷幻的事情。这不适合胆小的人。 :)


这是一个很好的答案:D 1. 所以选择器更像是方法本身的签名/路径?让编译器知道,这是你如何找到它的? 2. 我认为这比传递方法本身更有效。正确的? 3. 因为每个选择器和方法都有 1:1 的关系,并且由于这种效率,这就是你不通过方法的原因。 4. 你也可以举一个愚蠢的例子你也可以在运行时添加和删除方法我一直听说过,但我从来不需要这样做,我想也没有见过。
5a。我可以传递一个在选择器之间切换的条件参数吗? 5b。而不是将条件参数传递给选择器...为什么不只使用 if 语句创建一个方法?我想这是因为没有 if,我们的方法会变得更加 方法,按照他们所说的去做。得出结论,“状态处理”和围绕它的“动作”不应该采用相同的方法。
u
ughoavgfhw

方法是在要求对象或类执行某些操作时运行的实现。它在其包含类的范围内,因此在通过其他类引用时是不同的。选择器是代表方法名称的标识符。它与任何特定的类或方法无关,可以用来描述任何类的方法,无论是类方法还是实例方法。

简单地说,选择器就像字典中的键。它可以告诉您某人在谈论什么方法,但前提是您还拥有字典本身(类或对象)。该方法是当您使用选择器作为键从字典中请求值时得到的。


n
nstehr

该网站对所有相关术语都有很好的概述:http://www.otierney.net/objective-c.html

查看链接,但我将简要介绍一下:

方法本质上类似于您在喜欢的编程语言中习惯使用的函数方法。

消息(来自文章)“消息可以动态转发到另一个对象。在 Objective-C 中对对象调用消息并不意味着该对象实现了该消息,只是它知道如何通过某种方式响应它直接实现它或将消息转发给一个知道如何做的对象。”

选择器可能意味着两件事。它可以引用方法的名称,或者“引用在编译源代码时替换名称的唯一标识符。编译的选择器是 SEL 类型的。” (来自:http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Chapters/ocSelectors.html