Добавление задержки между выполнением двух следующих строк
Мне нужно добавить задержку между выполнением двух соседних строк(одинаковые) функции. Есть ли какие-то выгодные варианты для этого?
Примечание: для этого мне не нужны две разные функции, и задержка не должна влиять на выполнение других функций.
например:
line 1: [executing first operation];
line 2: Delay /* I need to introduce delay here */
line 3: [executing second operation];
любая помощь будет ощутимой. Спасибо заранее...
6 ответов:
вы можете использовать gcd для этого без необходимости создавать другой метод
double delayInSeconds = 2.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ NSLog(@"Do some work"); });
вы все равно должны спросить себя:" действительно ли мне нужно добавить задержку", поскольку это часто может усложнить код и вызвать условия гонки
можно использовать
NSThread
способ:[NSThread sleepForTimeInterval: delay];
однако, если вы сделаете это в основном потоке, вы заблокируете приложение, поэтому делайте это только в фоновом потоке.
или в Swift
NSThread.sleepForTimeInterval(delay)
в Swift 3
Thread.sleep(forTimeInterval: delay)
эта строка вызывает метод селектор после 3 секунд:
[self performSelector:@selector(secondMethod) withObject:nil afterDelay:3.0 ];
используйте его на вашей второй операции с желаемой задержкой. Если у вас много кода, поместите его в свой собственный метод и вызовите этот метод с помощью
performSelector:
. Он не будет блокировать пользовательский интерфейс, какsleep
Edit: если вы не хотите второй метод, вы можете добавить категорию, чтобы иметь возможность использовать блоки с performSelector:
@implementation NSObject (PerformBlockAfterDelay) - (void)performBlock:(void (^)(void))block afterDelay:(NSTimeInterval)delay { block = [block copy]; [self performSelector:@selector(fireBlockAfterDelay:) withObject:block afterDelay:delay]; } - (void)fireBlockAfterDelay:(void (^)(void))block { block(); } @end
или, возможно, даже чище:
void RunBlockAfterDelay(NSTimeInterval delay, void (^block)(void)) { dispatch_after(dispatch_time(DISPATCH_TIME_NOW, NSEC_PER_SEC*delay), dispatch_get_current_queue(), block); }
У меня есть несколько пошаговых игр, где мне нужно, чтобы ИИ сделал паузу, прежде чем принять свою очередь (и между шагами в свою очередь). Я уверен, что есть и другие, более полезные ситуации, когда задержка является лучшим решением. В Swift:
let delay = 2.0 * Double(NSEC_PER_SEC) let time = dispatch_time(DISPATCH_TIME_NOW, Int64(delay)) dispatch_after(time, dispatch_get_main_queue()) { self.playerTapped(aiPlayView) }
Я просто вернулся сюда, чтобы посмотреть, были ли вызовы Objective-C другими.(Мне нужно добавить это к этому тоже.)
Если вы нацелены на iOS 4.0+, вы можете сделать следующее:
[executing first operation]; double delayInSeconds = 2.0; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)); dispatch_after(popTime, dispatch_get_main_queue(), ^(void){ [executing second operation]; });
как писал @Sunkas,
performSelector:withObject:afterDelay:
это подвеска кdispatch_after
просто что он короче и у вас нормальныйobjective-c
синтаксис. Если вам нужно передать аргументы в блок, который вы хотите задержать, вы можете просто передать их через параметрwithObject
и вы получите его вselector
звоните:[self performSelector:@selector(testStringMethod:) withObject:@"Test Test" afterDelay:0.5]; - (void)testStringMethod:(NSString *)string{ NSLog(@"string >>> %@", string); }
если вы все еще хотите выбрать себя, если вы выполняете его в основном потоке или в текущем потоке, есть определенные методы, которые позволяют вам указать это. Яблоки Документация говорит об этом:
если вы хотите, чтобы сообщение было снято с очереди, когда цикл выполнения находится в режиме кроме режима по умолчанию, используйте performSelector:withObject:afterDelay: inModes: метод вместо этого. Если вы не уверены, является ли текущий поток основным потоком, вы можете используйте performSelectorOnMainThread:withObject:waitUntilDone: or performSelectorOnMainThread:withObject:waitUntilDone:modes: метод to гарантируйте, что ваш селектор выполняется на главном нитка. Чтобы отменить сообщение в очереди, используйте cancelPreviousPerformRequestsWithtarget: или cancelPreviousPerformRequestsWithtarget:селектор: объект: метод.