MMhunter MMhunter - 1 year ago 59
iOS Question

What risk will I take if i use delegate for communication between view controllers?

Recently when developing an iOS app, I encountered a problem that i need to have two view controllers to share some data, or even retrieve UI status from another view controller.

To honor this feature, i defined and implemented delegate for view controllers.

@protocol ViewControllerADelegate <NSObject>

-(id)dataForSomePurposeForViewController:(ViewController *)viewController


and then when pushing a new viewController(in ViewControllerA) class, I will set the currentViewController as delegate of the new controller if it is needed.

viewControllerA.delegate = currentViewController
[currentViewController.navigationController pushViewController:viewControllerA animated:YES]

After that I can call the delegate selector and get data from last view controller like:

//in viewControllerA
self.someData = [self.delegate dataForSomePurposeForViewController:self]

The code above is just an example showing what i have tried, there may be some typo in the code and do not pay too much attention to it.

In fact the above way works fine and never causes any problem up to now. But when i talked about this with one of my colleague, who is an Android developer, I was told that what i have done in iOS will not work in Android. In the task stack model in Android, the view controller (called Activity in Android) will not execute any code or respond to any function call when it is not at the top of the navigation stack.

This somehow makes me worry about my usage of delegate in this way. I googled a lot and now I know that my implementation is little bit against the MVC design pattern and the best way for communication between view controllers may be setting a shared model.

However changing the current code is a time consuming task. So My question is:

  1. What is the risk of using delegate for view controller communication?

  2. Is that as I understood that having a shared model to is the best practice? If yes, who should i assign this model to? by using singleton?

Any help or thinking is appreciated and thanks in Advance.

Answer Source

1)The risk is that top controller on stack can be not deallocated if u hold strong reference on it. Define delegate property as weak. Delegate pattern its not only one way to communicate between controllers. Also you can use blocks or notification center. Its matter of style.2)It depends on application architecture, sometimes its better to have shared model but in most cases delegates are good for communication. Below block example. Create property with type of block with copy attribute (why copy)

typedef void(^ApproveAction)(NSString *name);//return type(^name)(arguments)

@interface SecondViewController : UIViewController

@property (nonatomic, copy) ApproveAction onApproveTap;

+ (NSString *)storyboardID;


Then in firstViewController controller on some action we do next:

#pragma mark - Actions

- (IBAction)presentAction:(id)sender
    SecondViewController *secondVC = [self.storyboard instantiateViewControllerWithIdentifier:[SecondViewController storyboardID]];
    secondVC.onApproveTap = ^(NSString *name)

    [self presentViewController:secondVC animated:YES completion:nil];

To prevent retain cycle with block read this

Then again in SecondViewController call block when you should(for example on some button tap):

if (self.onApproveTap)//check if block not equal nil

!self.onApproveTap?:self.onApproveTap(@"name");//the same but with syntax sugar

Hope this helps.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download