Objective-C 中的选择器?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/738622/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 21:23:37  来源:igfitidea点击:

Selectors in Objective-C?

objective-cselector

提问by Craig

First, I'm not sure I really understand what a selector is. From my understanding, it's the name of a method, and you can assign it to a class of type 'SEL' and then run methods such as respondToSelector to see if the receiver implements that method. Can someone offer up a better explanation?

首先,我不确定我是否真的理解选择器是什么。根据我的理解,它是一个方法的名称,您可以将它分配给一个类型为“SEL”的类,然后运行诸如 respondToSelector 之类的方法来查看接收方是否实现了该方法。有人可以提供更好的解释吗?

Secondly, to this point, I have the following code:

其次,到目前为止,我有以下代码:

NSString *thing = @"Hello, this is Craig";

SEL sel = @selector(lowercaseString:);
NSString *lower = (([thing respondsToSelector:sel]) ? @"YES" : @"NO");
NSLog (@"Responds to lowercaseString: %@", lower);
if ([thing respondsToSelector:sel]) //(lower == @"YES")
    NSLog(@"lowercaseString is: %@", [thing lowercaseString]);

However, even though thingis clearly a kind of NSString, and should respond to lowercaseString, I cannot get the 'respondsToSelector' conditional to return "YES"...

但是,即使thing显然是一种 NSString,并且应该响应小写字符串,我也无法得到 'respondsToSelector' 条件返回“YES”...

回答by Adam Rosenfield

You have to be very careful about the method names. In this case, the method name is just "lowercaseString", not "lowercaseString:" (note the absence of the colon). That's why you're getting NOreturned, because NSStringobjects respond to the lowercaseStringmessage but not the lowercaseString:message.

您必须非常注意方法名称。在这种情况下,方法名称只是“ lowercaseString”,而不是“ lowercaseString:”(注意没有冒号)。这就是为什么你会被NO返回,因为NSString对象响应lowercaseString消息而不是lowercaseString:消息。

How do you know when to add a colon? You add a colon to the message name if you would add a colon when calling it, which happens if it takes one argument. If it takes zero arguments (as is the case with lowercaseString), then there is no colon. If it takes more than one argument, you have to add the extra argument names along with their colons, as in compare:options:range:locale:.

你怎么知道什么时候加冒号?如果在调用消息时添加冒号,则在消息名称中添加一个冒号,如果它接受一个参数就会发生这种情况。如果它接受零个参数(如lowercaseString),则没有冒号。如果需要多个参数,则必须添加额外的参数名称及其冒号,如compare:options:range:locale:.

You can also look at the documentationand note the presence or absence of a trailing colon.

您还可以查看文档并注意尾随冒号的存在与否。

回答by dstnbrkr

Selectorsare an efficient way to reference methods directly in compiled code - the compiler is what actually assigns the value to a SEL.

选择器是直接在编译代码中引用方法的有效方式——编译器实际上是将值分配给 SEL。

Other have already covered the second part of your q, the ':' at the end matches a different signature than what you're looking for (in this case that signature doesn't exist).

其他人已经涵盖了您的 q 的第二部分,末尾的 ':' 匹配的签名与您要查找的签名不同(在这种情况下,该签名不存在)。

回答by mipadi

That's because you want @selector(lowercaseString), not @selector(lowercaseString:). There's a subtle difference: the second one implies a parameter (note the colon at the end), but - [NSString lowercaseString]does not take a parameter.

那是因为你想要@selector(lowercaseString),而不是@selector(lowercaseString:)。有一个细微的区别:第二个隐含了一个参数(注意末尾的冒号),但- [NSString lowercaseString]不带参数。

回答by mkb

In this case, the name of the selector is wrong. The colon here is part of the method signature; it means that the method takes one argument. I believe that you want

在这种情况下,选择器的名称是错误的。这里的冒号是方法签名的一部分;这意味着该方法采用一个参数。我相信你想要

SEL sel = @selector(lowercaseString);

回答by Nicholas Riley

NSString's method is lowercaseString(0 arguments), not lowercaseString:(1 argument).

NSString 的方法是lowercaseString(0 个参数),而不是lowercaseString:(1 个参数)。

回答by Nicholas Riley

Don't think of the colon as part of the function name, think of it as a separator, if you don't have anything to separate (no value to go with the function) then you don't need it.

不要将冒号视为函数名称的一部分,将其视为分隔符,如果您没有任何要分隔的内容(该函数没有值),那么您就不需要它。

I'm not sure why but all this OO stuff seems to be foreign to Apple developers. I would strongly suggest grabbing Visual Studio Express and playing around with that too. Not because one is better than the other, just it's a good way to look at the design issues and ways of thinking.

我不知道为什么,但所有这些面向对象的东西对 Apple 开发人员来说似乎都是陌生的。我强烈建议抓住 Visual Studio Express 并使用它。不是因为一个比另一个更好,只是它是一种看待设计问题和思维方式的好方法。

Like

喜欢

introspection = reflection
+ before functions/properties = static
- = instance level

It's always good to look at a problem in different ways and programming is the ultimate puzzle.

以不同的方式看待问题总是好的,而编程是终极难题。

回答by moonman239

From my understanding of the Apple documentation, a selector represents the name of the method that you want to call. The nice thing about selectors is you can use them in cases where the exact method to be called varies. As a simple example, you can do something like:

根据我对 Apple 文档的理解,选择器表示您要调用的方法的名称。选择器的好处是您可以在要调用的确切方法发生变化的情况下使用它们。作为一个简单的例子,您可以执行以下操作:

SEL selec;
if (a == b) {
selec = @selector(method1)
}
else
{
selec = @selector(method2)
};
[self performSelector:selec];

回答by Adrian

As per apple docs: https://developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html

根据苹果文档:https: //developer.apple.com/library/archive/documentation/General/Conceptual/DevPedia-CocoaCore/Selector.html

A selector is the name used to select a method to execute for an object, or the unique identifier that replaces the name when the source code is compiled. A selector by itself doesn't do anything. It simply identifies a method. The only thing that makes the selector method name different from a plain string is that the compiler makes sure that selectors are unique. What makes a selector useful is that (in conjunction with the runtime) it acts like a dynamic function pointer that, for a given name, automatically points to the implementation of a method appropriate for whichever class it's used with. Suppose you had a selector for the method run, and classes Dog, Athlete, and ComputerSimulation (each of which implemented a method run). The selector could be used with an instance of each of the classes to invoke its run method—even though the implementation might be different for each.

选择器是用于为对象选择要执行的方法的名称,或者是在编译源代码时替换名称的唯一标识符。选择器本身不做任何事情。它只是标识一个方法。唯一使选择器方法名称与普通字符串不同的是编译器确保选择器是唯一的。选择器的有用之处在于(结合运行时)它就像一个动态函数指针,对于给定的名称,它自动指向适用于它所使用的任何类的方法的实现。假设您有一个用于方法 run 的选择器,以及类 Dog、Athlete 和 ComputerSimulation(每个类都实现了一个方法 run)。

Example: (lldb) breakpoint --set selector viewDidLoad

示例:(lldb) 断点 --set 选择器 viewDidLoad

This will set a breakpoint on all viewDidLoad implementations in your app. So selector is kind of a global identifier for a method.

这将在您的应用程序中的所有 viewDidLoad 实现上设置断点。所以选择器是一种方法的全局标识符。