Devfly
Devfly

Reputation: 2495

Confused about self and delegation

This code is from Utility app, added by Apple when creating a project.

What's the difference between this:

- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller
{
    [self dismissModalViewControllerAnimated:YES];
}

And this:

- (void)flipsideViewControllerDidFinish:(FlipsideViewController *)controller
{
    [controller dismissModalViewControllerAnimated:YES];
}

They both work, but the first one is the main code from Utility app, added by Apple. So is there any difference, and why does self works? self is MainViewController, not FlipsideViewController. I have no idea, does it has something to do with delegation? Thank you.

Upvotes: 3

Views: 162

Answers (2)

Alladinian
Alladinian

Reputation: 35626

I know that an answer has been already chosen as correct and Sergio have done a good job explaining delegation, but on this specific case the answer is far more simple. self and controller in this case are not the same thing (as you say also in the question). self is the presenting controller and controller is the presented one. So, the reason that both calls work is this:

The presenting view controller is responsible for dismissing the view controller it presented. If you call this method on the presented view controller itself, however, it automatically forwards the message to the presenting view controller.

From Apple's documentation on UIViewController

Upvotes: 2

sergio
sergio

Reputation: 69027

It all depends on which object is executing flipsideViewControllerDidFinish; if it is the same as the controller, then it is just the same.

In practice, what happens is that sometimes the class that is delegating (in your case FlipsideViewController), also implements the delegate protocol (ie., acts as a delegate). In such case, self and controller are the same. This would correspond to a delegate intialization (eg. in the init method) like:

 self.delegate = self;

But you could have your delegate be a different class (eg., the application delegate, or whatever) and in this case they would be different. In this case you would say (eg in init):

self.delegate = [UIApplication sharedApplication].delegate;

In this case, you application delegate would receive the call to FlipsideViewController and the controller argument tells which object it refers to; in this case, self != controller.

Another case is when your delegate is acting as a delegate for more than one object; in this case, the controller argument tells which object is the delegating one.

In practice, within the delegate method implementation you can safely use the controller argument without much thinking.

Upvotes: 2

Related Questions