Почему viewDidLoad ждет перед обновлением интерфейса? - PullRequest
3 голосов
/ 12 февраля 2010

Я просто пытаюсь разобраться в модели событий Objective-C на iPhone, и, судя по всему, здесь я кое-что неправильно понял.

В целях эксперимента в методе -view контроллера -viewDidLoad я устанавливаю текст UILabel, затем сплю в течение двух секунд, а затем снова изменяю текст метки.

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

Может кто-нибудь объяснить мне, что происходит? Мне интересно узнать, как вы, ребята, добьетесь того, ради чего я здесь иду.

Приветствие.

ОБНОВЛЕНИЕ 1 : вот метод viewDidLoad:

- (void)viewDidLoad {
    [super viewDidLoad];
    label.text = @"First Label";
    sleep(2);
    label.text = @"Second Label";
}

ОБНОВЛЕНИЕ 2 : Я допустил глупую ошибку, поэтому, пожалуйста, игнорируйте это обновление.

ОБНОВЛЕНИЕ 3 : Я добавил следующее в мой метод viewDidAppear:

- (void)viewDidAppear: (BOOL)animated {
    [super viewDidAppear: animated];
    label.text = @"First Label";
    sleep(2);
    label.text = @"Second Label";
}

К сожалению, у меня точно такая же проблема.

ОБНОВЛЕНИЕ 4 : Следуя советам gerry3 и Феликса, я теперь реализовал PerforSelector и boom! Работает лакомство !! Я собираюсь отдать его Джерри3, хотя он наверняка приложил максимум усилий, чтобы помочь мне. Спасибо за ваш вклад!

Ответы [ 4 ]

4 голосов
/ 12 февраля 2010

Я думаю, причина в том, что viewDidLoad работает на mainThread, как и все взаимодействия UIKit. Пользовательский интерфейс может быть обновлен только в mainThread, поэтому, если вы блокируете viewDidLoad с sleep(2), вы переводите mainThread в спящий режим и останавливаете все обновления пользовательского интерфейса в этом потоке.

Используйте NSTimer, если вы хотите обновить пользовательский интерфейс через определенное время, а не sleep(2). Или используйте performSelector:withDelay: для себя, чтобы выполнить метод позже, не блокируя mainThread.

То же самое верно для viewDidAppear и viewWillAppear. Оба запускаются на основном потоке.

3 голосов
/ 12 февраля 2010

Введите ваш код, который изменяет представление в viewDidAppear:.

Вид еще не виден при вызове viewDidLoad и viewWillAppear:.

UPDATE
Просто чтобы быть ясно, я согласен с другими, что правильный способ сделать это с помощью отложенного вызова метода или таймера.

ОБНОВЛЕНИЕ 2
Вот код, который я предлагаю:

- (void)viewDidLoad {
    [super viewDidLoad];
}

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

    NSLog(@"View will appear!");
}

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

    NSLog(@"View did appear!");

    label.text = @"First Label";
    sleep(2);
    label.text = @"Second Label";
}

И «правильный» путь:

- (void)viewDidLoad {
    [super viewDidLoad];

    label.text = @"First Label";
}

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

    NSLog(@"View will appear!");
}

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

    NSLog(@"View did appear!");

    [self performSelector:@selector(changeLabelText) withObject:nil afterDelay:2.0f];
}

- (void)changeLabelText {
    label.text = @"Second Label";
}
0 голосов
/ 12 февраля 2010

Сигнатура viewDidAppear и viewWillAppear неверны в вашем образце .. они должны быть

- (void)viewWillAppear: (BOOL)animated {
    NSLog(@"View will appear!");
}

-(void)viewDidAppear : (BOOL)animated {
    NSLog(@"View did appear!");
}

Фреймворки не будут вызывать реализации с неверной подписью, так как отправка сообщений не находит их.

0 голосов
/ 12 февраля 2010

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...