2014-10-12 79 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

相關問題