我需要在同一个函数中的两行代码执行之间添加延迟。有没有合适的选项可以实现这个功能?
注意:我不需要使用两个不同的函数来实现这个功能,而且延迟不能影响其他函数的执行。
例如:
line 1: [executing first operation];
line 2: Delay /* I need to introduce delay here */
line 3: [executing second operation];
我需要在同一个函数中的两行代码执行之间添加延迟。有没有合适的选项可以实现这个功能?
注意:我不需要使用两个不同的函数来实现这个功能,而且延迟不能影响其他函数的执行。
例如:
line 1: [executing first operation];
line 2: Delay /* I need to introduce delay here */
line 3: [executing second operation];
你可以使用gcd函数来完成此操作,而无需创建另一个方法。
// ObjC
NSTimeInterval 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");
});
// Swift
DispatchQueue.main.asyncAfter(deadline: .now() + 2) {
print("Do some work)
}
在添加延迟之前,您仍应该问自己“我真的需要添加延迟吗”,因为它经常会使代码复杂化并引起竞态条件。
您可以使用NSThread
方法:
[NSThread sleepForTimeInterval: delay];
但是,如果您在主线程上执行此操作,将会阻塞应用程序,因此请仅在后台线程上执行此操作。
或者使用Swift语言:
NSThread.sleepForTimeInterval(delay)
在 Swift 3 中
Thread.sleep(forTimeInterval: delay)
这行代码会在3秒钟后调用选择器secondMethod:
[self performSelector:@selector(secondMethod) withObject:nil afterDelay:3.0 ];
在您进行第二个操作时使用它,并设置所需的延迟。如果您有很多代码,请将其放入自己的方法中,并使用performSelector:
调用该方法。这不会像sleep
那样阻塞UI。
编辑:如果您不想要第二个方法,可以添加一个类别以便能够使用带有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);
}
performSelector
:https://dev59.com/XG865IYBdhLWcg3wEKSZ - Sunkas[self performBlock:^{ your_code } afterDelay:0.1];
- Sunkas我有几个回合制游戏,需要AI在进行其回合之前(以及在其回合的步骤之间)暂停。我相信还有其他更有用的情况下,延迟是最好的解决方案。在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);
}