Ожидание указанной продолжительности в Какао - PullRequest
26 голосов
/ 09 февраля 2010

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

- (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];
}

Ответы [ 7 ]

67 голосов
/ 09 февраля 2010

Есть

usleep(1000000);

и

[NSThread sleepForTimeInterval:1.0f];

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

10 голосов
/ 09 февраля 2010

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

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

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

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

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

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

NSString *something = ...;
RunAfterDelay(0, ^{
    NSLog(@"%@", something);
    [self doWorkWithSomething: something];
});
2 голосов
/ 09 февраля 2010

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

2 голосов
/ 09 февраля 2010

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

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

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

0 голосов
/ 18 сентября 2016

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

[[NSOperationQueue currentQueue] addOperationWithBlock:^{
    [self doStuffAfterWaiting];
}];
0 голосов
/ 09 февраля 2010

Tadah !

Чуть более информативно, ссылка указывает на NSThread sleepForTimeInterval:

Это было фактически украдено из: Что эквивалентно Java Thread.sleep () в Objective-C / Cocoa?

...