我希望将来可以安排三个小事件而无需为每个事件编写一个函数。如何使用NSTimer
执行此操作?我理解块有助于匿名功能,但它们是否可以在NSTimer
内使用,如果是,如何使用?
[NSTimer scheduledTimerWithTimeInterval:gameInterval
target:self selector:@selector(/* I simply want to update a label here */)
userInfo:nil repeats:NO];
答案 0 :(得分:56)
如果你想要实现类似于NSTimer和块执行的东西,你可以使用dispatch_after。
以下是相同的示例代码:
int64_t delayInSeconds = gameInterval; // Your Game Interval as mentioned above by you
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
// Update your label here.
});
希望这有帮助。
答案 1 :(得分:25)
你实际上可以打电话:
NSTimer.scheduledTimerWithTimeInterval(ti: NSTimeInterval,
target: AnyObject,
selector: #Selector,
userInfo: AnyObject?,
repeats: Bool)
像这样使用:
NSTimer.scheduledTimerWithTimeInterval(1,
target: NSBlockOperation(block: {...}),
selector: #selector(NSOperation.main),
userInfo: nil,
repeats: true)
答案 2 :(得分:17)
A block based timer API exists in Cocoa(从iOS 10+ / macOS 10.12+开始) - 以下是在Swift 3中使用它的方法:
animation: {
animateScale: true,
animateRotate: true,
onComplete: function () {
var chartInstance = this.chart,
ctx = chartInstance.ctx;
ctx.font = Chart.helpers.fontString(Chart.defaults.global.defaultFontSize, Chart.defaults.global.defaultFontStyle, Chart.defaults.global.defaultFontFamily);
ctx.textAlign = 'center';
ctx.fillStyle = this.chart.config.options.defaultFontColor;
ctx.textBaseline = 'bottom';
this.data.datasets.forEach(function (dataset, i) {
var meta = chartInstance.controller.getDatasetMeta(i);
meta.data.forEach(function (bar, index) {
data = dataset.data[index];
ctx.fillText(data, bar._model.x, bar._model.y - 5);
});
});
}
}
......或在Objective-C中:
Timer(timeInterval: gameInterval, repeats: false) { _ in
print("herp derp")
}
如果您需要定位早于iOS10,macOS 12,tvOS 10,watchOS 3的操作系统版本,则应使用其他解决方案之一。
答案 3 :(得分:9)
@Peter Peng的Objective-C版回答:
_actionDelayTimer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:[NSBlockOperation blockOperationWithBlock:^{
NSLog(@"Well this is useless.");
}] selector:@selector(main) userInfo:nil repeats:YES];
答案 4 :(得分:6)
这很简单,但它不包含在Apple框架中,至少还没有。
您可以自己为NSTimer
编写基于块的包装器,例如使用GCD,或者您可以使用现有的第三方库:https://github.com/jivadevoe/NSTimer-Blocks。
答案 5 :(得分:3)
我在NSTimer上创建了一个类别,可以将它与块一起使用。
答案 6 :(得分:2)
Timer.scheduledTimer(withTimeInterval: 0.25, repeats: true) { timer in
print("no, seriously, this works on iPhone")
}
这要感谢@JohnnyC!
真的很奇怪!
答案 7 :(得分:0)
我爱这个黑客@Peter-Pang !! BlockOperation是动态创建的,由运行队列本身拥有的Timer拥有,并调用块上的主选择器来运行它....很好!!!
已更新Swift 3
Timer.scheduledTimer(timeInterval: 1, target: BlockOperation {
// ...
}, selector: #selector(Operation.main), userInfo: nil, repeats: false)
答案 8 :(得分:0)
我已经创建了一个宏,它将执行此操作并自动处理dealloc,arc,remaining cycle等。无需担心使用弱引用。它也将始终位于主线程上
#define inlineTimer(__interval, __block) {\
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((0.0) * NSEC_PER_SEC)), dispatch_get_main_queue(), (__block));\
[NSTimer scheduledTimerWithTimeInterval:__interval repeats:YES block:^(NSTimer *__timer) {\
if (self.window != nil) {\
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)((0.0) * NSEC_PER_SEC)), dispatch_get_main_queue(), (__block));\
} else {\
[__timer invalidate];\
}\
}];\
}
用法示例:
__block ticks = 0;
inlineTimer(0.5, ^{
ticks++;
self.label.text = [NSString stringWithFormat:@"Ticks: %i", ticks];//strong reference to self and self.label won't cause retain cycle! Wahoo
});
请注意,self.label不是弱引用,但是由于宏的结构,所有这些都会自动释放。
自然地,这仅适用于UI类,因为它正在检查.window何时应取消分配。