我试图让我的应用程序在延迟后执行一个操作,但必须在用户与UIScrollView
.
我不确定为什么两者都不会performSelector:withObject:afterDelay
或scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
不会开火。是因为他们在后台线程上吗?
有什么建议或帮助吗?
我试图让我的应用程序在延迟后执行一个操作,但必须在用户与UIScrollView
.
我不确定为什么两者都不会performSelector:withObject:afterDelay
或scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:
不会开火。是因为他们在后台线程上吗?
有什么建议或帮助吗?
两者NSTimer
并且performSelector:withObject:afterDelay:
默认情况下仅在正常运行循环模式下触发。滚动时,运行循环处于事件跟踪模式。
您必须在所有常见模式下安排定时操作:
NSTimer *timer = [NSTimer timerWithTimeInterval:0.016 target:self selector:@selector(fire:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];
或者
[self performSelector:@selector(fire:) withObject:nil afterDelay:1.0 inModes:[NSArray arrayWithObject:NSRunLoopCommonModes]];
还有专用的NSEventTrackingRunLoopMode
。
确保延迟触发发生在NSRunLoopCommonModes
. 默认值是NSDefaultRunLoopMode
在滚动时不会收到消息。
[self performSelector:@selector(fire:) withObject:nil afterDelay:2.0 inModes:@[NSRunLoopCommonModes]];
或者,您可以使用GCD
which 也以相同的方式运行(不确定它使用哪种运行循环模式)
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){
<#code to be executed on the main queue after delay#>
});
对于斯威夫特:
performSelector(#selector(fire:), withObject: sender, afterDelay: 1.0, inModes: [NSRunLoopCommonModes])