2

On my main view controller I have a button which shows another view controller, where some settings can be changed:

PresentViewController (new UINavigationController(anotherViewController), true, null);

For the dismiss of anotherViewController the parent should be responsible. I also have to know if something has changed (saved). Therefore I use events.

I'm attaching the event handlers in viewWillAppear on my parent view controller

anotherViewController.DismissMe += CancelEventHandler;
anotherViewController.SaveFilter += SaveEventHandler;

and in viewWillDisappear I'm unsubscribing from it

anotherViewController.DismissMe -= CancelEventHandler;
anotherViewController.SaveFilter -= SaveEventHandler;

Because viewWillDisappear is triggered when a new view controller is presented, I automatically unsubscribe from the events. When I want to fire the events in anotherViewController I can't, because no one is subscribed to my events.

I have to unsubscribe from the events, because otherwise the view controller is never released.

How can I solve this situation?

testing
  • 19,681
  • 50
  • 236
  • 417
  • `viewWillAppear` and `viewWillDisappear` are not good delegate methods to put that kind of logic, since they may run whenever and never. I'd go with subscribing in `init` and unsubscribing in `dealloc`, since they are called exactly once. – Simon Aug 20 '15 at 12:25
  • @Simon: Therefore I used a boolean variable to know if I have subscribed one time or not. Is the `init` or the constructor a good idea? There are some [side effects](http://stackoverflow.com/a/26653294/426227), which brings a kind of mess in the view controller life cycle under certain circumstances . I'd have to move the code from `viewDidLoad` to `init`. Is the `dealloc` not too late? Or would the memory management be fine here? – testing Aug 20 '15 at 12:46
  • 1
    I don't really know how xamarin or monotouch works, but I do know the life cycles of iOS view controllers. As long as you don't touch the `viewController's` view in `init`, I'd say you subscribe there. And for `dealloc`, that's the place to unsubscribe and clean up your hooks. So, if you don't need the `view` property, add your subscribes to `init`, otherwise add it to `loadView` _after_ the super call. – Simon Aug 20 '15 at 12:49
  • If I follow your approach then I could leave my code as it is (subscription in `viewDidLoad`) and unssubscribe in `dealloc`. Would this be a good idea? Another approach which comes to my mind is to use another boolean variable here. Then I would have to set it on each present and dismiss. And in `viewWillDisappear` I could check it if I should unsubscribe or not. – testing Aug 20 '15 at 12:55
  • that would also work. the design is up to you! – Simon Aug 20 '15 at 13:07
  • 1
    Have a look at this duplicate? http://stackoverflow.com/questions/1816614/viewwilldisappear-determine-whether-view-controller-is-being-popped-or-is-showi – der_michael Aug 20 '15 at 18:50
  • @der_michael: Thanks for the link. This does not fully address my problem, because I need to detect when the user navigates back to the origin view controller. Here the events are added every time, when `viewWillAppear` is called. I could use another boolean variable where I store how the view controller was dismissed. – testing Aug 21 '15 at 08:42

1 Answers1

2

My current solution looks like the following:

Before I present the new view controller I'm subscribing to the events for cancel and save (custom created events). Because the presenting view controller gets this events (cancel, save) when the presented view controller is closed or a save operation is done, I remove subscriptions to this events (cancel, save) when I retrieve one of those. Id est in the event handler itself I'm unsubscribing from the event.

With this it should be assured that I only subscribe one time and that I also unsubscribe when needed.

There are more approaches to this, which can be found in the comments to my question.

testing
  • 19,681
  • 50
  • 236
  • 417