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

Ожидание определенной продолжительности в Cocoa

Есть ли более простой способ подождать определенное количество времени в Cocoa, чем то, что я придумал ниже?

- (void) buttonPressed {
    [self makeSomeChanges];

    // give the user some visual feedback and wait a bit so he can see it
    [self displayThoseChangesToTheUser];
    [self performSelector:@selector(buttonPressedPart2:) withObject:nil afterDelay:0.35];
}

- (void) buttonPressedPart2: (id)unused {
    [self automaticallyReturnToPreviousView];
}

Просто, чтобы быть ясным, нет проблемы с функциональным с этим кодом - моя единственная говядина - это стилистическая. В моем случае поток достаточно прост, что он работает, но попытайтесь инкапсулировать его или выбросить некоторые условные выражения, и все может стать уродливым. Мне было очень неловко, что я не мог найти способ подождать, а затем вернуться к той же точке кода, как этот (фиктивный) пример:

- (void) buttonPressed {
    [self doStuff];
    [UIMagicUnicorn waitForDuration:0.35];
    [self doStuffAfterWaiting];
}
4b9b3361

Ответ 1

Существует

usleep(1000000);

и

[NSThread sleepForTimeInterval:1.0f];

оба из которых будут спать в течение 1 секунды.

Ответ 2

Здесь используется способ NSTimer. Это может быть даже уродливее, чем метод, который вы используете, но он позволяет повторять события, поэтому я предпочитаю его.

[NSTimer scheduledTimerWithTimeInterval:0.5f 
                                 target:self
                               selector: @selector(doSomething:) 
                               userInfo:nil
                                repeats:NO];

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

Ответ 3

Я не уверен, что он существует (пока), но с блоками в 10.6 (или PLBlocks в 10.5 и на iPhone) должно быть довольно легко написать небольшую обертку, например performBlock:afterDelay:, которая делает именно то, что вы хотите, без необходимости спать весь поток. Было бы действительно полезным кусочком кода.

Майк Эш написал об этом подобном в своем блоге:

NSString *something = ...;
RunAfterDelay(0, ^{
    NSLog(@"%@", something);
    [self doWorkWithSomething: something];
});

Ответ 4

Вероятно, вы захотите использовать NSTimer и отправить сообщение "doStuffAfterWaiting" в качестве своего обратного вызова. Любой "сон" блокирует поток, пока он не просыпается. Если это в вашем U.I. нить, это приведет к тому, что ваше приложение появится "мертвым". Даже если это не так, это плохая форма. Подход обратного вызова освободит CPU для выполнения других задач, пока не будет достигнут указанный вами временной интервал.

Этот doc содержит примеры использования и обсуждает различия в том, как и где создавать ваш таймер.

Конечно, performSelector: afterDelay: делает то же самое.

Ответ 5

Что не так с простым usleep? Я имею в виду, за исключением "Cocoa чистоты", он все еще намного меньше, чем другие решения:)

Ответ 7

Если вы не против асинхронного решения, вы здесь:

[[NSOperationQueue currentQueue] addOperationWithBlock:^{
    [self doStuffAfterWaiting];
}];