NSTimer具有匿名功能/块?

时间:2013-02-17 19:07:01

标签: iphone objective-c nstimer

我希望将来可以安排三个小事件而无需为每个事件编写一个函数。如何使用NSTimer执行此操作?我理解块有助于匿名功能,但它们是否可以在NSTimer内使用,如果是,如何使用?

[NSTimer scheduledTimerWithTimeInterval:gameInterval  
         target:self selector:@selector(/* I simply want to update a label here */) 
         userInfo:nil repeats:NO];

9 个答案:

答案 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上创建了一个类别,可以将它与块一起使用。

https://github.com/mBrissman/NSTimer-Block

答案 6 :(得分:2)

截至2018年底,您正是这样做的:

Timer.scheduledTimer(withTimeInterval: 0.25, repeats: true) { timer in
  print("no, seriously, this works on iPhone")
} 

这要感谢@JohnnyC!

真的很奇怪!

enter image description here

答案 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何时应取消分配。