Удаление вида из iOS Superview - PullRequest
0 голосов
/ 06 января 2012

Я пытаюсь понять, почему первый метод, приведенный ниже, работает для сокрытия и удаления подпредставления представления. В этом первом методе я передаю указатель по ссылке. Во втором методе, который носит менее общий характер, у меня есть метод делегата, предназначенный для удаления конкретного представления. Я хотел бы использовать первый метод, потому что у меня есть несколько представлений, которые я хотел бы применить это тоже. Я должен упомянуть, что первый метод работает без сбоев до тех пор, пока он вызывается внутри реализующего класса. Это не удается, когда я вызываю его из контроллера представления, который я хочу отклонить. Я получаю EXC_BAD_ACCESS в строке removeFromSuperview при сбое в первом методе.

-(void)closeView:(UIViewController **)viewController
{
 [UIView transitionWithView:self.view 
                   duration:UINavigationControllerHideShowBarDuration
                    options:UIViewAnimationOptionCurveLinear
                 animations:^
  {
   [[*viewController view] setAlpha:0.0];
  }
                 completion:^(BOOL finished)
  {   
   [[*viewController view] removeFromSuperview];
   [*viewController release], *viewController = nil;
  }];
}

-(void)closeButtonClicked
{
 [delegate closeView:&self];
}

//
// This method works without fail:
//

-(void)closeView
{
 [UIView transitionWithView:self.view 
                   duration:UINavigationControllerHideShowBarDuration
                    options:UIViewAnimationOptionCurveLinear
                 animations:^
  {
   // In this context viewController is defined in the class interface
   [[viewController view] setAlpha:0.0];
  }
                 completion:^(BOOL finished)
  {      
   [[viewController view] removeFromSuperview];
   [viewController release], viewController = nil;       
  }];
}

-(void)closeButtonClicked
{
 [delegate closeView];
}

Ответы [ 2 ]

2 голосов
/ 07 января 2012

Прежде всего, это не в соответствии с руководствами по стилю, и не очень хорошая идея делать релиз viewController внутри метода, подобного этому.Это быстро доставит вам неприятности.Если вызывающий этого метода отвечает за viewController (он сделал сохранение), то он должен также освободить его.Вероятно, это является причиной того, что первый метод не работает из самого viewcontroller.

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

Если вы не выпускаете viewController в этом методе, вам также не нужно устанавливать его переменную равной nil, и вы можете просто передать его как обычный параметр:

-(void)closeView:(UIViewController *)viewController
{
 [UIView transitionWithView:self.view 
                   duration:UINavigationControllerHideShowBarDuration
                    options:UIViewAnimationOptionTransitionCrossDissolve
                 animations:^
  {
    [[viewController view] removeFromSuperview];
  }
                 completion:nil];
}

youзатем сделал бы это на сайте вызова:

[self closeView:childViewController];
[childViewController release]; childViewController = nil;

Безопасным образом освободить дочерний объект до завершения анимации, поскольку блок анимации неявно сохраняет все объекты, на которые есть ссылки из блока, включая viewControllerпараметр.Следовательно, дочерний коллектор не вызывается до тех пор, пока блок анимации не освободит его.Это не работает в вашем первом примере кода, потому что вы передаете указатель на переменную.То есть блок анимации не знает, что ему нужно сохранить дочерний элемент.

Кстати, я не уверен, почему вы хотите установить альфа, в приведенном выше примере я показываю, что вы также можете удалить представление ужев блоке анимации.Подробнее об этом см. В справочнике классов UIView .

0 голосов
/ 06 января 2012

** viewcontroller и & self - это не тот путь. В Objective-C вы делаете [self.view removeFromSuperview] в самом подпредставлении, в родительском контроллере представления вы делаете release или с ARC просто заменяете подпредставление другим представлением.

...