开发者

Why (id)sender instead of (UIButton *)sender

开发者 https://www.devze.com 2023-03-05 14:00 出处:网络
I am trying to learn about Objective-C for iPhone development, and while going through examples about actions I often saw things like:

I am trying to learn about Objective-C for iPhone development, and while going through examples about actions I often saw things like:

- (IBAction)sliderMoved:(id)sender
{
    UISlider *aSlider = (UISlider *)sender;
    //rest of code goes here...
}

What is the purpose of taking in type (id) and then immediately casting it to (UISlider *). Why开发者_如何学C not just have the following:

- (IBAction)sliderMoved:(UISlider *)aSlider;
{
    //rest of code goes here...
}

Is there a technical reason for this, or is it simply convention, or done for readability?

Thanks in advance,

  • Timo


I believe it is a convention that stems from the fact that there is not always a 1:1 mapping of UIControl to IBAction. For example, you could have a UISwitch, a UIButton, and a UITextField all mapped to a - (IBAction)syncUI:(id)sender; method. In that case, it is impossible to specify the type.

I admit that this is just my own mental justification, and there is certainly nothing preventing you from being more explicit in the type of sender if you can be. I usually am.


You can, in fact, specify the sender as UIButton* if you want to, and if you're absolutely certain that that action should never be triggered by any other kind of object. That might even be appropriate if the action depends on the sender being a particular type. Usually, though, the type of the sender doesn't matter to the controller, and specifying it as id gives you flexibility to change your view without having to modify the controller.

One reason you might want that kind of flexibility, even if you know you'll always use a button in your app for the action in question, is that it makes unit testing that much easier.


IBActions are usually generic and can be triggered by any class, hence the id type. If you need to cast the sender variable within your method, then obviously you care about the class of sender, so you should change the method signature to reflect that.


id is the abstract data type. If your method can be called from multiple places, by another object, through a button, etc. then you may not always know what type of object is sending the method call. I think it is mostly convention, if you're going to poll the sender for data you have to know what methods it can respond to (if not you can ask with respondsToSelector:).

0

精彩评论

暂无评论...
验证码 换一张
取 消