Can a child view controller "dismiss itself?" .....
You have a view controller "RedMessage". You have an ordinary strong property for it ...
@property (strong) RedMessage *red;
You add it ("modally") on top of your current VC...
self.red = (RedMessage *)[self.storyboard
instantiateViewControllerWithIdentifier:@"RedMessageID"];
self.red.view.frame = self.view.frame;
[self.view addSubview:self.red.view];
[self addChildViewController:self.red];
[self.red didMoveToParentViewController:self];
To get rid of it later, do this
[self.red willMoveToParentViewController:nil];
[self.red.view removeFromSuperview];
[self.red removeFromParentViewController];
BUT IN FACT, do you need to do this??
[rm willMoveToParentViewController:nil];
[rm.view removeFromSuperview];
[rm removeFromParentViewController];
rm = nil;
Do you need the "= nil;" ?
Note that this question is critical, because: if you do NOT HAVE TO nil it, you can then do the following inside the new view controller...
-(void)dismissMyselfCompletely
{
[self willMoveToParentViewController:nil];
[self.view removeFromSuperview];
[self removeFromParentViewController];
}
Which is extremely convenient.
In short, if you do that inside the new top view controller - will it "work", does it release the VC?
When removeFromParentViewController happens, does the parent VC understand it can release self.red?
After considerable testing, we found that it appears to be the case that:
it does go away and is not retained.
We add the VC on top like this (just in the usual way you add a "modal" VC on top...)
-(void)showOverlay:(NSDictionary*)dict
{
Red *rr = (Red *)[self.storyboard
instantiateViewControllerWithIdentifier:@"RedID"];
rr.view.frame = self.view.bounds;
[self.view addSubview:rr.view];
[self addChildViewController:rr];
[rr didMoveToParentViewController:self];
[rr useThisData:dict];
}
Note that there's no Property holding rr - it is just created and added on the fly in that category.
Inside "Red" we get rid of it just like this...
-(void)dismiss:(UITapGestureRecognizer *)sender
{
[self.view exitLeftSmoothly:0 then:^
{
[self willMoveToParentViewController:nil];
[self.view removeFromSuperview];
[self removeFromParentViewController];
}];
}
(exitLeft is just an animation, not relevant)
Finally you can test it like this:
-(void)viewDidAppear:(BOOL)animated
{
[super viewDidAppear:animated];
....
[self _teste];
}
-(void)_teste
{
Red __weak *mySelf = self;
dispatch_after_secs_on_main(0.5, ^
{
NSLog(@"tick !!!!!!!!!!!!");
if ( mySelf == nil ) NSLog(@"I no longer exist - WTF!");
[mySelf _teste];
});
}
You can see clearly that once the "Red" vc is dismissed, indeed, the ticker stops running: "Red" has gone away.
It does seem to work reliably. Your output will look something like this...
2014-10-22 17:26:36.498 [1738:111092] tick --- !!!!!!!!!!!!
2014-10-22 17:26:37.031 [1738:111092] tick --- !!!!!!!!!!!!
2014-10-22 17:26:37.576 [1738:111092] tick --- !!!!!!!!!!!!
2014-10-22 17:26:38.124 [1738:111092] tick --- !!!!!!!!!!!!
2014-10-22 17:26:38.674 [1738:111092] tick --- !!!!!!!!!!!!
2014-10-22 17:26:39.217 [1738:111092] tick --- !!!!!!!!!!!!
2014-10-22 17:26:39.764 [1738:111092] tick --- !!!!!!!!!!!!
2014-10-22 17:26:39.764 [1738:111092] I no longer exist --- WTF!
To reiterate, as AnujYadav points out, if you use a property in the parent VC for the "Red"...
@property (strong) Red *red;
then
self.red = (Red *)[self.storyboard
instantiateViewControllerWithIdentifier:@"RedID"];
etc ... indeed this DOES NOT work. In that case, you would have to self.red=nil in the parent, or it will not go away.
This is more memory management question than view controller containment one. No you don't need to put nil there, but...
You are assuming that you have a reference to it. Question is: is it strong reference? if yes, than you have to nil it, because that view controller will not be dellocated. Easiest way to test it is to add -dealoc method to rm with log message.
There seems to be a difference in your question and answer. In your overlay method (in answer) you did not assigned the ViewController to any strong property and in question you have strong property. I have not tested the code but I feel you should update your test to have a strong property.
I think ideally we should "nil" the property. Otherwise, from stack yes view controller will be removed.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With