2013-11-12 3 views
8

Я создаю пользовательские переходы в своем приложении и сталкиваюсь с двумя проблемами. Если я установил контроллер представления для обработки как UIViewControllerAnimatedTransitioning, так и UIViewControllerTransitioningDelegate, я столкнулся с проблемой моего контроллера наблюдения, который никогда не освобождается. В частности, это создает сохранить:пользовательский iOS 7 цикл сохранения перехода UIViewController

self.transitioningDelegate = self; 

Если я не делаю этого, и положить UIViewControllerAnimatedTransitioning и UIViewControllerTransitioningDelegate в отдельном NSObject называется TransitionController и установить его так:

self.transitioningDelegate = [[TransitionController alloc] init]; 

UIViewController является deallocated, но я получаю утечки памяти в объекте TransitionController. Кто-нибудь теперь, что я делаю неправильно?

ответ

6

Я столкнулся с тем же вопросом и смог его решить.
Пользовательский API перехода не так хорошо документирован и требует много проб и ошибок, чтобы я мог все исправить.

Позвольте мне вас через, как я был в состоянии сделать это прекрасно работать без каких-либо проблем с памятью:

Вот игроки:

VCA = Контроллер вид, что хочет представить VCB модально
VCB = Модифицированный контроллер представления (представлен VCA)

TC = Пользовательский объект контроллера перехода, который выполняет пользовательскую анимацию.
Подкласс NSObject, который соответствует «UIViewControllerAnimatedTransitioning».
Будет создан экземпляр внутри TD.

TD = Пользовательский объект делегирования перехода, который предоставляет контроллер перехода в систему. NSObject подкласс, который соответствует "UIViewControllerTransitioningDelegate"

Теперь давайте представить экземпляр VCB

себя = экземпляр СВУ
myModalViewController = сильное свойство личности

self.myModalViewController = [[VCB alloc] init]; 

[self.myModalViewController setModalPresentationStyle: UIModalPresentationCustom]; 
[self.myModalViewController setTransitioningDelegate: [[TD alloc] init]]; 
[self presentViewController: self.myModalViewController 
        animated:YES 
       completion:NULL]; 

В в какой-то момент, VCB просит отклонить VCA

self = экземпляр VCA
myModalViewController = модально представлен пример VCB представил ранее

[self dismissViewControllerAnimated:YES 
         completion:^{ 
      [self.myModalViewController setTransitioningDelegate: nil]; // DO THIS!!!! 
      self.myModalViewController = nil; 
     }]; 



Я надеюсь, что это помогает. Это, безусловно, для меня.

+0

Это похоже на iOS 7.1 –

+0

transitioningDelegate - это небезопасное неиспользуемое свойство, вам нужно где-то сильно сохранить TD (рекомендую в другом пользовательском свойстве myModalVC). – Chris

0

Во второй попытке вы назначаете экземпляр TransitionController, и он никогда не будет выпущен (так как никто не ссылается на него). Объекты не должны сохранять своих делегатов в Objective-C, поэтому вам нужно иметь ссылку на ваш ViewController и на его номер delegate из другой точки вашего кода.

2

В моем случае я имел себя (UIViewController), удерживающий экземпляр обычая UIViewController (назовем его mViewController), и self является transitioningDelegate показать/увольнения mViewConroller. Мое решение, чтобы избежать сохранения цикла было назвать это внутри .m из mViewController:

-(void)viewDidDisappear:(BOOL)animated { 
    self.transitioningDelegate = nil; 
    [super viewDidDisappear:animated]; 
} 

Работал как шарм (:

+0

Конечно, вы должны вызвать [super viewDidDisappear: animated] в конце этой функции – ingaham

+1

@ingaham true, спасибо за указание, отредактировал мой ответ –

0

Объект UIViewControllerAnimatedTransitioning удерживается «от» VC после переход заканчивается в iOS7 (это не происходит в iOS8), что может вызвать утечку памяти, если ваш объект перехода хранит что-либо в свойствах. Это немного меня в прошлом, что-то нужно соблюдать.

0

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

[transitionContext completeTransition:transitionContext.transitionWasCancelled]; 

Это должно было это:

BOOL successful = transitionContext.transitionWasCancelled == NO; 
[transitionContext completeTransition:successful]; 

Нарезка код на две строки помогает читаемость.

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