Что именно будут делать MoveToParentViewController: и сделалиMoveToParentViewController:?

Я знаю, что, начиная с iOS5 и новых методов сдерживания UIViewController, вы должны вызывать эти методы вместе с addChildViewController:, removeFromParentViewController: и методом перехода. Я также знаю правильный порядок их вызова в трех сценариях. Чего я не знаю, так это того, что именно делают эти методы?

Если бы это были просто точки переопределения для подклассов UIViewController, я думаю, нам не нужно было бы вызывать super при переопределении. Что может пойти не так, если я не вызову willMoveToParentViewController: nil перед удалением контроллера представления или didMoveToParentViewController: self?


person konrad    schedule 16.10.2012    source источник


Ответы (2)


В дополнение к тому, что было сказано, они вызывают некоторые методы делегата:

addChildViewController звонит [child willMoveToParentViewController:self]

и removeFromParentViewController: звонит [child didMoveToParentViewController:nil]

Кроме того, они модифицируют свойство childViewControllers, которое содержит массив дочерних контроллеров представления.

person Guillaume    schedule 16.10.2012
comment
Да, я знаю, что «добавить» и «удалить» вызывают один метод автоматически (willMove... и didMove... соответственно) и требуют, чтобы вы вызывали другой вручную. Я думаю, у меня нет проблем с пониманием того, что делают «добавить» и «удалить» - это кажется довольно простым. Я просто чувствую себя немного сбитым с толку относительно того, что на самом деле делают «воля» и «делал». - person konrad; 16.10.2012
comment
will и did не имеют конкретной реализации, вы вызываете их на дочернем контроллере, а если нет, то они просто не вызываются... что может быть проблемой, если дочерний контроллер их реализовал и полагался на них. В своем ответе я ошибочно назвал их методами делегирования, но это почти то, чем они являются, они функционируют как необязательные методы делегирования, и ребенок может использовать их для некоторой настройки или очистки. Любой подкласс UIViewController может переопределить их, и если вы реализуете контроллер контейнера, вы должны уважать это поведение и вызывать их. - person Guillaume; 16.10.2012
comment
Чтобы было ясно, willMoveToParentViewController: и didMoveToParentViewController: UIViewController ничего не делают. Однако любой подкласс позволяет их переопределять, поэтому, если вы их не вызовете, вы не сломаете голый UIViewController, но вы сломаете подклассы, которые полагаются на него (например: скажем, подкласс хочет освободить объект, когда он удаляется из родительского контроллера представления, если вы не вызываете метод, он никогда не освободит объект). - person Guillaume; 16.10.2012
comment
Хорошо, это проясняет. Так что это своего рода дополнительный протокол. Недавно я пытался найти некоторые ошибки в управлении иерархией контроллеров представления и обнаружил, что забыл вызвать их в нескольких местах. Вот тогда я и начал задаваться вопросом, что может испортиться в таком случае. Оказывается, пока я не переопределяю их в подклассах UIViewController, которые я добавляю/удаляю, это не должно ни на что влиять (что, очевидно, не означает, что вы не должны их вызывать). Большое спасибо! - person konrad; 16.10.2012
comment
@Guillaume -- у меня есть для тебя! Что, если это НОВЫЙ контроллер представления, который вы только что создали (instantiateViewControllerWithIdentifier). В таком случае абсолютно безопасно НЕ ВЫЗЫВАТЬ didMoveToParentViewController, поскольку он не движется? Преимущество того, что вы не вызываете его, заключается в том, что вы избегаете раздражающей проблемы 2x viewWillAppear. ваше здоровье! - person Fattie; 31.08.2014
comment
@Guillaume, не могли бы вы указать шаг использования containerview - person Ravi Ojha; 05.02.2015

На это есть много ответов:

  1. Они есть, и вы должны призывать их, когда это применимо, чтобы всегда поддерживать шаблон. Таким образом, если вы измените суперклассы с UIViewController на свой собственный контроллер представления, вам не придется беспокоиться о том, где вы следовали всему шаблону.

  2. Лучше зацепиться за них, чем просить всех переопределить addChildViewController:. Как вы сказали, неправильное управление willMoveToParentViewController: кажется менее опасным, чем неправильное управление addChildViewController:, особенно если вы забыли позвонить super.

  3. UIViewController вероятно, зависит от того, придерживаетесь ли вы шаблона. Возможно, он сочтет состояние несогласованным, если узнает, что получил addChildViewController:, но никогда не получил два других сообщения. Происходит ли это из-за того, что UIViewController ведет учет, чтобы заманить вас в поддержку полного шаблона, или вы действительно испортили его внутреннее состояние — это забавная игра в догадки, но также и то, что может измениться в любой версии iOS. Вещи могут сильно сломаться. Вот почему существует шаблон, чтобы Apple сказала вам, что, пока вы это делаете, мы будем поддерживать работу, несмотря ни на что.

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

person Jesper    schedule 16.10.2012
comment
Я не хочу задавать вопросы, используя эти методы. Если в документах Apple говорится, что «вы должны» позвонить им, на это наверняка есть причина. Я просто надеюсь, что кто-то с немного большим опытом и знанием механизма вложения UIViewControllers объяснит это более подробно, чем официальные документы, в которых только говорится, что он «информирует» дочерний контроллер представления об изменении. Моя теория заключается в том, что это позволяет некоторую подготовку и очистку, если вы хотите, чтобы переход был анимирован, но это всего лишь предположение. - person konrad; 16.10.2012
comment
О, вот для чего он будет использоваться, если вы создадите подкласс UIViewController. Я хотел сказать, что даже если он ничего не делает, знание этого не сделает вызов super чем-то, чего вам следует избегать. Возможно, это лучше всего резюмируется тем, что делает его намного менее беспорядочным, потому что вам не придется переопределять addChildViewController: (пункт 2). - person Jesper; 16.10.2012