Objective-C中的选择器是另一种向对象发送消息的方式吗?

lam*_*ade 6 objective-c objective-c-runtime selector

Objective-C中的选择器是另一种向对象发送消息的方式吗?我真的不明白为什么或如何使用它们.

BJ *_*mer 21

当您想要定义回调机制时,通常会使用选择器.Cocoa中选择器最常见的用例是控件,如按钮.A UIButton非常通用,因此不知道按下按钮时会发生什么.在使用之前,您需要告诉它按下按钮时应该运行什么方法.这样做如下:

[myButton addTarget:self
             action:@selector(myButtonWasPressed)
   forControlEvents:UIControlEventTouchUpInside];

- (void)myButtonWasPressed {
    // Do something about it
}
Run Code Online (Sandbox Code Playgroud)

然后,当按下按钮时,按钮将调用我们传递它的目标上的选择器.使用此机制,每次希望它调用您自己的代码时,您都不需要子类化按钮.相反,UIButton它本身有一个通用的机制,可以调度你选择的任何代码.(好的,从技术上讲,它UIControl是提供调度机制的超类.)


Jen*_*ton 16

它们不是向对象发送消息的另一种方式,它们是唯一的方式.例如,in [myView setValue:@"foo"],setValue:是一个选择器.(编写相同内容的另一种不太方便的方法是objc_msgSend(myView, @selector(setValue:), @"foo").)

正如Ian Henry所说,您可以使用SEL值在运行时选择选择器而不是编译时.这是Cocoa的一项基本技术; 用户界面通常使用目标/动作绑定连接到控制器,其中目标是对象,动作是选择器.通常你在一个笔尖中设置它,但你也可以在代码中这样做:

[myButton setTarget:myController];
[myButton setAction:@selector(buttonClicked:)]; // Clicking the button will now call [myController buttonClick:myButton].
Run Code Online (Sandbox Code Playgroud)

  • 通过设置操作,单击按钮时将发送消息.如果您直接发送消息,则会"立即"发生(即,在设置UI时).在加载窗口时立即单击所有按钮通常不常用. (3认同)
  • lampShade:不,如果您直接向自己发送`addItem:`消息*而不是将其设置为按钮的动作,则会发生这种情况.该按钮不参与.该按钮仅在您将自己设置为其目标时(在IB中或在代码中;它无关紧要)和`addItem:`作为其操作,并且仅在用户单击按钮时发送该消息.使按钮将其动作消息发送到其目标.(另外,Cocoa中的动作选择器必须带一个参数,因此:我在这个注释中附加到`addItem:`.) (3认同)