2014-10-12 3 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?

Когда удаляетсяFromParentViewController, родительский VC понимает, что он может освободить self.red?

+0

Bounty для справки. – Fattie

+0

Извините, что предоставил собственный ответ, но мы тщательно его протестировали и нашли результат, указанный в ответе ... надеюсь, что это поможет кому-то! – Fattie

ответ

12

После основательного тестирования, мы обнаружили, что, как представляется, дело, что:

вы можете фактически позволить Биотех «удалить себя.»

он уходит и не сохраняется.

Добавляет VC сверху, как это (только обычным способом вы добавить «модальные» КИ сверху ...)

Обратите внимание, что нет собственности холдинговой р-р - это просто создан и добавил «на лету» в этой категории.

Внутри «Красного» мы избавляемся от него именно так ...

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

Вы можете ясно видеть, что когда-вк «Красный» является уволенный, действительно, тикер перестает работать: «Красный» ушел.

Он действительно работает надежно. Ваш выход будет выглядеть примерно так ...

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

Спасибо, что поделились своими исследованиями здесь! У меня в течение некоторого времени была небольшая ошибка (редко ударить) в моем настраиваемом контроллере контейнеров, и это может помочь мне найти ее. – eric

+0

Да, в этой проблеме много путаницы. Надеюсь, поможет! – Fattie

3

Это больше вопросов управления памятью, чем защита контроллера. Нет, вам не нужно ставить нуль, но ...

Вы предполагаете, что у вас есть ссылка на него. Вопрос в том, что это сильная ссылка? если да, то вам нужно это сделать, потому что этот контроллер просмотра не будет удален. Самый простой способ проверить это - добавить метод -dealoc в rm с сообщением журнала.

+0

действительно - это вопрос памяти, поэтому наслаждайтесь щедростью! :) – Fattie

2

Кажется, что в вашем вопросе и ответе есть разница. В вашем методе оверлея (в ответ) вы не присвоили ViewController любому сильному свойству, и в вопросе у вас есть сильное свойство. Я не тестировал код, но чувствую, что вы должны обновить свой тест, чтобы иметь сильное свойство.

Я думаю, что в идеале мы должны «нуль» собственности. В противном случае, из стека да контроллер будет удален.

+0

Привет anuj - правильный: в примере «этот метод работает» в ответе, который я вставляю, как сказано ... * «Обратите внимание, что нет свойства hold rr - он просто создан и добавлен« на лету »в этой категории . * * – Fattie

+0

Hi Joe - Извините, я пропустил это. Вы также проверяете наличие сильной собственности? –

+0

Эй, Анудж - точно. Как и следовало ожидать, если вы используете свойство, в родительском VC ... он не исчезнет! (FTR отметим, что я на самом деле просто использую категорию для выполнения этой работы .. из VC, который он просто вызывает [self showOverlay] ;, он даже не упоминает «красный» класс.) – Fattie

Смежные вопросы