Каков наилучший способ отправки параметров в UIViewController? - PullRequest
0 голосов
/ 29 сентября 2011

Я задаю этот вопрос, потому что кажется, что viewDidLoad вызывается раньше, чем основной блок инициализатора, и переменные класса, которые я инициализирую в инициализаторе, обнуляются в viewDidLoad.Для справки, я делаю весь этот viewcontroller программно и создал собственный инициализатор, чтобы я мог принимать различные параметры, которые будут использоваться в моем viewcontroller.Мой пользовательский инициализатор вызывает UIViewControllers, назначенный, конечно же, инициализатором.

По сути, мне интересно, каков правильный шаблон проектирования для отправки параметров в UIViewController?Я читал другие темы по этому поводу и не получил окончательного ответа.Должен ли я просто пропустить инициализатор и установить свойства вручную (вне класса)?Это кажется чем-то плохим, я действительно хотел бы отправить некоторые параметры, и мне любопытно, как другие поступают так?

Ответы [ 3 ]

8 голосов
/ 29 сентября 2011

Причина, по которой viewDidLoad вызывается до завершения инициализации, возможно потому, что вы вызываете метод view в инициализаторе.Например:

- (id)init
{
    if ((self = [super init])) {
        _thing = 123;
        _other = self.view.frame.size.width / 2;
    }

    return self;
}

viewDidLoad вызывается при загрузке представления.И представление загружается, как только вы вызываете метод view (или обращаетесь к свойству представления, если хотите).Поэтому вам следует избегать ссылки на представление в init.

Чтобы ответить на ваш вопрос, я предпочитаю создать метод init для моих контроллеров представления.

- (id)initWithThing:(MyThing *)thing thang:(MyThang *)thang
{
    if ((self = [super init])) {
        _thing = [thing retain];
        _thang = [thang retain];
        // ...
    }

    return self;
}

Вы также можете использовать свойства для установки дополнительныхпеременные после инициации.Лично я предпочитаю делать это только с необязательными свойствами и помещать обязательные свойства в метод init.Таким образом, я не могу инициализировать контроллер представления с недопустимым состоянием.

1 голос
/ 29 сентября 2011

Я инкапсулирую состояние моих контроллеров в дополнительный объект состояния.Поэтому в контроллере обычно есть ivars для элементов GUI и ссылка на этот объект состояния.

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

Любой класс может получить состояние любого другого контроллера и изменить его.Это цель некоторых контроллеров (например: выбор видео с YouTube происходит на выделенном контроллере).Но обычно это только один класс, получающий состояние для отправки следующего контроллера с помощью initWithState :.Затем выдвинутый контроллер применяет состояние к своему графическому интерфейсу в viewDidLoad или изменяет этот объект состояния, переданный из предыдущего класса.

StateManager хранит словарь всех объектов состояния.Я сохраняю свет на графике объекта состояния, например: я сохраняю ссылку на изображение, но не само изображение.Настоящая проблема приложения - в Core Data, я использую все это только для обработки состояния графического интерфейса.StateManager прослушивает событие отставки приложения и сохраняет словарь состояний на диск с помощью NSCoding.Ивары объекта состояния всегда равны нулю или имеют какое-то значимое значение, без висячих указателей.

Я работаю над своим вторым приложением для iPhone, и это, кажется, работает, но мне также интересно, как это делают другие люди.Любые входные данные приветствуются.

1 голос
/ 29 сентября 2011

В основном у вас должны быть свойства, определенные для ваших входных данных, но добавьте пользовательскую функцию init.Если вы создадите пользовательский метод init, у вас все будет в порядке - помните, что initWithNibName:bundle: является основным инициализатором UIViewController, так что это то, что вы хотите вызвать из вашего пользовательского метода init.viewDidLoad всегда будет вызываться после вашего метода init при первом использовании customVC.view (из вашего кода или через Framework):

- (id)initWithDataObject:(MyDataObject*)obj
{
    self = [super initWithNibName:nil bundle:nil];
    if (self) {
        self.dataObj = obj;
    }
    return self;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...