3

I am a newbie iOS programmer, here is my question: I have mapview and segmented control, also changeMapType function which get called when UIControlEventValueChanged occures, like this

// change map type with segmented control
- (IBAction)changeMapType:(id)sender
{
    NSInteger i = [mapTypeControl selectedSegmentIndex];
    if (i == 0){
        [worldView setMapType:MKMapTypeStandard];
    }
    if (i == 1) {
        [worldView setMapType:MKMapTypeSatellite];
    }
    if (i == 2) {
        [worldView setMapType:MKMapTypeHybrid];
    }
}

and in viewDidLoad I want to call this method to set up which map type is first.

[mapTypeControl setSelectedSegmentIndex:2];
[self changeMapType:nil];

above code works fine, but below code works fine either

[mapTypeControl setSelectedSegmentIndex:2];
[self changeMapType:self];

so finally, what to pass as SENDER? which is correct?

smoke
  • 67
  • 1
  • 6

5 Answers5

2

Conceptually, neither one is correct, in practice, both are fine.

sender is (or at least should be) the UIControl instance (the segmented control in your case) that initiates the action. In fact, you should begin your method like this:

- (IBAction)changeMapType:(UISegmentedControl *)sender
{
    NSInteger i = [sender selectedSegmentIndex];

    // etc.
}

And when calling manually, you should pass in the segmented control:

[self changeMapType:mapTypeControl];
  • what about xcode's giving us (id)sender ? You suggest to change for all actions? Anywaz liked your pic as compared to penguins :) – Anoop Vaidya Mar 08 '13 at 08:54
  • @AnoopVaidya IDK why it defaults to `id`, in these cases, it's always an instance of `UIControl`. Xcode is crap. –  Mar 08 '13 at 08:55
  • in osx sometimes it is NSComboBox, NSButton etc, so I guess they wanted to make it generic. Isn't it, and after getting (id)sender, we convert : `UIButton *button=(UIButton *)sender` – Anoop Vaidya Mar 08 '13 at 08:57
  • @AnoopVaidya We're talking about iOS here. –  Mar 08 '13 at 08:58
  • yes, the documentation says it should be (id)sender, I guess to cover all the cases. – smoke Mar 08 '13 at 11:04
0

Since you're not really doing anything with "sender" (being passed into your IBAction method), you can pass pretty much anything you want along.

Use "self" or "nil" and you should be just fine.

If you do end up using "sender" within any of your IBActions, then you do need to care about what you send along programatically. When you click a button or some object in a user interface that's connected to your action, a reference to that object is what gets sent.

p.s. it's like an answer party in here!

Michael Dautermann
  • 88,797
  • 17
  • 166
  • 215
0

either is fine, since you dont even use sender in your method... its usually there in case the method needs to know something about what object used the function so you can go if([sender isKindOfClass:[SomeObject class]])

Fonix
  • 11,447
  • 3
  • 45
  • 74
0

For an IBAction, the sender is the interface object that sent the message call. In your instance, triggering this programmatically, there isn't such an object, so you should pass nil.

Purpletoucan
  • 6,472
  • 2
  • 21
  • 28
0

I agree with the other answers -- since you don't use sender, you can pass whatever you want.

Actually, I would suggest you to change the method to not take a sender parameter at all.

- (IBAction)changeMapType

Control actions can have 3 possible signatures:

- (IBAction)changeMapType
- (IBAction)changeMapType:(id)sender
- (IBAction)changeMapType:(id)sender forEvent:(UIEvent *)event

It is best to take the additional parameters only if you use them.

And once you get rid of that parameter, you won't have to worry about what to pass for it. And this solution is actually correct -- you are not passing something in that is not really the sender.

If you pass in something random like nil, you may one day decide to use the sender parameter, and forget that you passed junk in in one place, causing problems. However, if you removed the parameter altogether, then when you need to use the sender parameter, you will need to change the method name, which involves changing all the places that call it (or else it won't compile, since the method name changed). So you can't accidentally screw up.

newacct
  • 119,665
  • 29
  • 163
  • 224