我有一个数组,其中包含以毫秒为单位的时间值,例如:
let executionTimes = [0, 1500, 3500, 4700]
最重要的是,有一个功能只是做任何事情 - 现在 - 打印一些文字:
func printHello() {
print("Hello")
}
我想要做的是在数组中给定的时间段后执行该函数。因此,printHello()将立即执行,然后在1.5秒后执行,然后再执行2秒,最后再执行1,2秒,然后再从开始执行。现在我希望这个函数调用时间能够“永远”继续。
首先我尝试使用NSTimer来解决这个问题,但是从我发现的情况来看,无法动态更改计时器的timeInterval而不会先使其失效,这会使用给定的时间表进行调整。
然后我认为使用performSelector可以解决这个问题:
func executeCustomScheduler(timeIndex: Int) {
let time: Double = executionTimes[timeIndex]
NSLog("Hello")
let nextTimeIndex = timeIndex == (executionTimes.count - 1) ? 0 : timeIndex + 1
self.performSelector(Selector(executeCustomScheduler(nextTimeIndex)), withObject: self, afterDelay: time)
}
这根本不起作用,因为函数正在执行而没有任何延迟,并且由于我认为的递归调用而遇到崩溃。
有人可以提供任何有用的提示吗?
非常感谢!
答案 0 :(得分:0)
您可以使用NSTimer
。
NSDate *date = [[NSDate date] dateByAddingTimeInterval:someInterval];
NSTimer *timer = [[NSTimer alloc] initWithFireDate:date interval:0 target:self selector:@selector(timerFired:) userInfo:info repeats:NO];
[[NSRunLoop mainRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];
这样,您可以将时间间隔添加到日期,并在此时计划定时器(是的,每个时间间隔中的许多时间段)。希望这可以帮助。此外,如果您希望以后随时invalidate
计时器,则应将计时器保留在某个数组中。祝你好运!
PS。抱歉,客观的事情,希望你能把它转换成swift。
答案 1 :(得分:0)
这里有很多错误:
Selector(executeCustomScheduler(nextTimeIndex))
根据一次执行executeCustomScheduler(nextTimeIndex)
的返回值withObject: self
- 你为什么要通过self
?performSelector
?executionTimes
不是以毫秒为单位,而是以秒为单位,或者至少方法需要它们performSelector
解决方案:
Selector("executeCustomScheduler:")
是正确的选择器nextTimeIndex
是传递performSelector
String
代替Int
:/ 更好的解决方案:
使用dispatch_after
,摆脱那些讨厌的选择器并一直保持类型安全:
class Obj {
let executionTimes = [0, 1500, 3500, 4700]
func executeCustomScheduler(timeIndex: Int) {
NSLog("Hello")
let time = executionTimes[timeIndex]
let nextTimeIndex = (timeIndex + 1) % executionTimes.count
let delayTime = dispatch_time(DISPATCH_TIME_NOW, Int64(Double(time) / 1000 * Double(NSEC_PER_SEC)))
dispatch_after(delayTime, dispatch_get_main_queue()) {
self.executeCustomScheduler(nextTimeIndex)
}
}
}
let obj = Obj()
obj.executeCustomScheduler(0)
答案 2 :(得分:0)
您不必使用我们NSTimer
来实现您的目标。事实上,解决问题的方法非常简单。
Swift 中的示例解决方案:
let executionTimes = [1000.0, 1500.0, 3500.0, 4700.0]
for executionTime in executionTimes {
self.performSelector(#selector(printHello(_:)), withObject: NSNumber(double: executionTime), afterDelay: executionTime/1000.0)
}
func printHello(executionTime: NSNumber) {
let doubleValue = executionTime.doubleValue
print("Hello \(doubleValue)")
}
请注意,您不能将struct作为标有withObject:
标签的参数传递。这就是为什么我用Double
(这是一个类)包装NSNumber
(这是一个结构)实例。
Objective-c 中的示例解决方案:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
NSArray<NSNumber *> *executionTimes = @[@(1000.0), @(1500.0), @(3500.0), @(4700.0)];
for (NSNumber *executionTime in executionTimes) {
[self performSelector:@selector(printHello:) withObject:executionTime afterDelay:executionTime.doubleValue/1000];
}
return YES;
}
- (void)printHello:(NSNumber *)executionTime
{
NSLog(@"Hello %@", executionTime.stringValue);
}