2014-10-12 107 views
9

儿童视图控制器可以“自行解散?” .....removeFromParentViewController - 之后你需要零吗?


你有一个视图控制器“RedMessage”。你有一个普通的强大财产...

@property(strong)RedMessage * red;

您对您目前的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]; 

若要后来摆脱它,这样做

[self.red willMoveToParentViewController:nil]; 
[self.red.view removeFromSuperview]; 
[self.red removeFromParentViewController]; 

但事实上,你需要这样做?

[rm willMoveToParentViewController:nil]; 
[rm.view removeFromSuperview]; 
[rm removeFromParentViewController]; 
rm = nil; 

您是否需要“= nil;” ?

注意,这个问题是至关重要的,因为:如果你没有到零,你可以再做新的视图控制器内以下......

-(void)dismissMyselfCompletely 
    { 
    [self willMoveToParentViewController:nil]; 
    [self.view removeFromSuperview]; 
    [self removeFromParentViewController]; 
    } 

这是非常方便的。

总之,如果你在新的顶部视图控制器内部做到这一点 - 它会“工作”,它会释放VC吗?

当removeFromParentViewController发生时,父VC是否明白它可以释放self.red?

+0

恩惠用于授权引用。 – Fattie 2014-10-16 06:50:37

+0

对不起,提供自己的答案,但我们做了广泛的测试,并找到答案中给出的结果...希望它可以帮助别人! – Fattie 2014-10-22 09:32:27

回答

12

相当大的测试之后,我们发现,它似乎是这样:

你其实可以允许VC为“删除自身。”

它确实消失并且不被保留。

我们添加VC对这样的顶部(只是添加在顶部的“模式” VC通常的方式......)

注意,有没有持有物业RR - 这是刚刚创建并在该类别中随时添加。

里面的“红色”我们摆脱它就像这样...

-(void)dismiss:(UITapGestureRecognizer *)sender 
    { 
    [self.view exitLeftSmoothly:0 then:^ 
     { 
     [self willMoveToParentViewController:nil]; 
     [self.view removeFromSuperview]; 
     [self removeFromParentViewController]; 
     }]; 
    } 

(exitLeft只是一个动画,不相关)

最后,你可以测试它像这样

-(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]; 
     }); 
    } 

你可以清楚地看到,一旦 “红” 是VC被解散了,事实上,股票停止运行:“红色”已经消失。

它确实似乎可靠地工作。输出将是这个样子......

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! 

要重申,作为AnujYadav指出,如果你父VC为“红”使用属性 ...

@property (strong) Red *red; 

然后

self.red = (Red *)[self.storyboard 
instantiateViewControllerWithIdentifier:@"RedID"]; 

等......事实上,这是行不通的。在这种情况下,你将不得不在self.red = nil中,否则将不会消失。

+1

感谢您分享您的研究!我在自定义容器视图控制器中有一段唠叨(罕见罢工)的bug,这可能会帮助我找到它。 – eric 2015-05-22 16:40:13

+0

是的,这个问题存在很多混淆。希望能帮助到你! – Fattie 2015-05-22 16:55:12

3

这是比视图控制器遏制更多的内存管理问题。不,你不需要放在那里,但...

你假设你有一个参考。问题是:它是否是强有力的参考?如果是的话,那么你必须删除它,因为该视图控制器不会被取消分配。测试它的最简单方法是将-dealoc方法与日志消息一起添加到rm中。

+0

确实 - 这是一个记忆问题,所以,享受赏金! :) – Fattie 2014-10-23 19:14:19

2

你的问题和答案似乎有所不同。在覆盖方法中(在答案中),您没有将ViewController分配给任何强大的属性,并且问题中您拥有强大的属性。我没有测试过这些代码,但我觉得你应该更新你的测试以拥有一个强大的属性。

我认为理想情况下我们应该“无”财产。否则,从堆栈视图控制器将被删除。

+0

嗨anuj - 正确的:在“我的方法有效”的例子中,我放入了,就像它说的那样... *“请注意,没有Property持有rr - 它只是在该类别中创建和添加。“* – Fattie 2014-10-22 15:10:26

+0

嗨乔 - 对不起,我错过了那个。你还检查了强大的财产? – 2014-10-22 15:23:23

+0

嘿Anuj - 完全正确。就像你所期望的那样,如果你使用一个属性,在父VC中......它不会消失! (FTR请注意,我实际上只是使用一个类别来完成这个工作......在VC中它只是调用[showOverlay];它甚至没有提到“Red”类)。 – Fattie 2014-10-22 15:30:37

相关问题