smoke
smoke

Reputation: 67

self IBAction and sender

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?

Upvotes: 3

Views: 2179

Answers (5)

newacct
newacct

Reputation: 122449

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.

Upvotes: 0

user529758
user529758

Reputation:

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];

Upvotes: 2

Purpletoucan
Purpletoucan

Reputation: 6572

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.

Upvotes: 0

Fonix
Fonix

Reputation: 11597

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]])

Upvotes: 0

Michael Dautermann
Michael Dautermann

Reputation: 89509

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!

Upvotes: 0

Related Questions