Подтвердить что ты не робот

IOS 7 - Разница между viewDidLoad и viewDidAppear

Извините, но это может быть не вопрос программирования, а более подробная информация о характере функций жизненного цикла iOS.

У меня есть приложение, в котором у меня есть функция, которая создает четыре массива и заполняет их с помощью запросов к базе данных. Сначала я вызывал функцию из функции viewDidLoad, однако, всякий раз, когда вид загружается, требуется время (около 3-4 секунд) до появления представления. Итак, что я сделал, я создал activityViewIndicator, а моя функция viewDidLoad выглядит примерно так:

- (void)viewDidLoad:(BOOL)animated{
    [super viewDidLoad];

    NSLog(@"viewDidLoad Entered");
    [self.activityIndicatorView startAnimating];

    partInput.delegate = self;
    brandInput.delegate = self;
    barcodeInput.delegate = self;
    itemNameInput.delegate = self;

    //initializeArrays is the function that initializes the arrays
    [self initializeArrays];

    [self.activityIndicatorView stopAnimating];

}

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

- (void)viewDidAppear:(BOOL)animated{
    NSLog(@"viewDidAppear loaded successfully");
    [self.activityIndicatorView startAnimating];

    partInput.delegate = self;
    brandInput.delegate = self;
    barcodeInput.delegate = self;
    itemNameInput.delegate = self;

    [self initializeArrays];

    [self.activityIndicatorView stopAnimating];

}

Однако, когда я развернул это, не было никакой задержки, сделав ActivityIndicatorView бесполезным.

Мой вопрос: почему мне кажется, что существует "разница в производительности" между viewDidLoad и viewDidAppear?

4b9b3361

Ответ 1

Пожалуйста, следуйте приведенному ниже циклу жизненного цикла контроллера. Таким образом вы будете поражены кодированием и эффективностью вашего приложения.

enter image description here

Ответ 2

Я собираюсь указать вам документы Apple, потому что я думаю, что есть необходимость в более подробном объяснении жизненного цикла View Controller, а не просто ответе на ваш вопрос как сформулированный.

https://developer.apple.com/library/ios/featuredarticles/ViewControllerPGforiPhoneOS/ViewLoadingandUnloading/ViewLoadingandUnloading.html

В конечном счете, ваш контроллер просмотра имеет жизненный цикл:

init - однако вы инициализируете свой контроллер просмотра

viewWillLoad/viewDidLoad - вызывается при создании представления (через первый вызов для получения контроллера представления UIView через него свойство просмотра - aka lazy loading)

viewWillAppear: - когда представление готово появиться либо сразу (анимированное == НЕТ), либо просмотреть переход (анимированный == ДА)

viewDidAppear: - если вид представления не был отменен, и полностью отображается представление контроллера просмотра

viewWillDisappear: - дополняет viewWillAppear:

viewDidDisappear: - дополняет viewDidAppear:

viewWillUnload/viewDidUnload - устаревшие API, когда представление выгружается из-за ограничений памяти (больше не беспокойтесь об этом)

dealloc - сам диспетчер представлений освобождается

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

- (void)viewDidLoad
{
    [super viewDidLoad];

    // other stuff

    __weak typeof(self) weakSelf = self;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        typeof(weakSelf) strongSelf = weakSelf;
        if (strongSelf) {
            [strongSelf initializeArraysSynchronously];
            dispatch_async(dispatch_get_main_queue(), ^{
                strongSelf.doneIntializingArrays = YES;
                [strongSelf.activityIndicatorView stopAnimating];
            });
        }
    });
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    if (!self.doneInitializingArrays) {
        [self.activityIndicatorView startAnimating];
    } 
}

Ответ 3

Однако, когда вы загружаете вещи с сервера (или тяжелая обработка данных), вы также должны думать о задержке. Если вы упакуете всю свою сетевую связь в viewDidLoad или viewWillAppear, они будут выполнены до того, как пользователь увидит представление - возможно, это приведет к короткому замораживанию вашего приложения. Это может быть хорошей идеей, чтобы сначала показать пользователю незаселенное представление с индикатором активности. Когда вы закончите работу с сетью, которая может занять секунду или два (или может даже не срабатывать - кто знает?), Вы можете заполнить представление своими данными. Хорошие примеры того, как это можно сделать, можно увидеть в разных клиентах Twitter. Например, когда вы просматриваете страницу подробностей автора в Twitterrific, в представлении указывается только "Загрузка..." до тех пор, пока сетевые запросы не будут завершены.

ViewDidLoad вызывает только один раз, когда вы каждый раз инициализировали ваш ViewController, но Viewdidapper.

Ответ 4

activityIndicatorViews будет только анимировать, если основной поток (поток пользовательского интерфейса) не занят. viewDidLoad: и viewDidAppear: выполняются в основном потоке. Если, как вы говорите, метод initializeArrays не выполняется в отдельном потоке, тогда activityIndicatorViews никогда не будет времени для анимации.

Ответ 5

Абсолютно нет разницы в производительности между viewDidLoad: и viewDidAppear:. Оба являются нормальными функциями, запущенными на основном потоке. Если ваш метод initializeArrays занимает 3 секунды для загрузки, это займет 3 секунды в зависимости от того, какой метод вы его вызываете. Поскольку вы явно не изменяете потоки, любая функция, в которой вы вызываете initializeArrays, не будет выходить до ее завершения.

Вызов [self.activityIndicatorView startAnimating] будет в основном "отмечать" ActivityIndicatorView, чтобы другая функция пользовательского интерфейса в основном потоке начала анимацию. (Вот почему основной или "пользовательский" поток важны, потому что на нем координируются все анимации и визуальные обновления на экране). Таким образом, функция, которая на самом деле приведет к запуску ActivityIndicator, не будет вызвана до завершения инициализацииArray, и вы уже вызвали "stopAnimating".

Попробуйте следующее:

- (void)viewDidLoad:(BOOL)animated{
    [super viewDidLoad];

    NSLog(@"viewDidLoad Entered");
    [self.activityIndicatorView startAnimating];

    partInput.delegate = self;
    brandInput.delegate = self;
    barcodeInput.delegate = self;
    itemNameInput.delegate = self;
}

- (void)viewDidAppear:(BOOL)animated{
    //initializeArrays is the function that initializes the arrays
    [self initializeArrays];
    [self.activityIndicatorView stopAnimating];
}

Ответ 6

View Did Load. Первый метод, который вызывается, когда первый раз загружается, но не отображается на экране/окне, загружается только.

только одно время, когда просмотр загружается впервые.

Вид появился. После вызова viewWillAppear будет вызываться viewDidAppear. Это означает, что на экране теперь отображается вид.

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

**

  • Просмотр жизненного цикла

**

1) ViewDidLoad (вызывается только при первом загрузке представления), затем 2) ViewWillAppear (будет называться количество раз), затем 3) ViewDidAppear (будет называться количество раз), затем 4) ViewWillDisAppear (будет называться количество раз), затем 5) ViewDidDisAppear (будет называться количество раз)