我有一个简单的类,init
方法采用Int和回调函数。
class Timer {
var timer = NSTimer()
var handler: (Int) -> Void
init(duration: Int, handler: (Int) -> Void) {
self.duration = duration
self.handler = handler
self.start()
}
@objc func someMethod() {
self.handler(10)
}
}
然后在ViewController中我有:
var timer = Timer(duration: 5, handler: displayTimeRemaining)
func displayTimeRemaining(counter: Int) -> Void {
println(counter)
}
这不起作用,我得到以下内容:
'Int' is not a subtype of 'SecondViewController'
编辑1:添加完整代码。
Timer.swift
import UIKit
class Timer {
lazy var timer = NSTimer()
var handler: (Int) -> Void
let duration: Int
var elapsedTime: Int = 0
init(duration: Int, handler: (Int) -> Void) {
self.duration = duration
self.handler = handler
self.start()
}
func start() {
self.timer = NSTimer.scheduledTimerWithTimeInterval(1.0,
target: self,
selector: Selector("tick"),
userInfo: nil,
repeats: true)
}
func stop() {
timer.invalidate()
}
func tick() {
self.elapsedTime++
self.handler(10)
if self.elapsedTime == self.duration {
self.stop()
}
}
deinit {
self.timer.invalidate()
}
}
SecondViewController.swift
import UIKit
class SecondViewController: UIViewController {
@IBOutlet var cycleCounter: UILabel!
var number = 0
var timer = Timer(duration: 5, handler: displayTimeRemaining)
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view, typically from a nib.
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
// Dispose of any resources that can be recreated.
}
@IBAction func btnIncrementCycle_Click(sender: UIButton){
cycleCounter.text = String(++number)
println(number)
}
func displayTimeRemaining(counter: Int) -> Void {
println(counter)
}
}
我刚开始使用Swift,所以我非常环保。你打算如何通过回调?我看过一些例子,我认为这应该是有效的。我的类是否因我传递回调的方式而被错误地定义了?
由于
答案 0 :(得分:16)
好的,现在有了完整的代码我能够复制你的问题。我不是100%确定原因是什么,但我认为它与在实例化类之前引用类方法( displayTimeRemaining )有关。以下是一些解决方法:
选项1:在 SecondViewController 类之外声明处理程序方法:
func displayTimeRemaining(counter: Int) -> Void {
println(counter)
}
class SecondViewController: UIViewController {
// ...
var timer = Timer(duration: 5, handler: displayTimeRemaining)
选项2:通过将class关键字添加到函数声明中,将 displayTimeRemaining 转换为类型方法。
class SecondViewController: UIViewController {
var timer: Timer = Timer(duration: 5, handler: SecondViewController.displayTimeRemaining)
class func displayTimeRemaining(counter: Int) -> Void {
println(counter)
}
选项3:我相信这将是最符合Swift思维方式的内容 - 使用闭包:
class SecondViewController: UIViewController {
var timer: Timer = Timer(duration: 5) {
println($0) //using Swift's anonymous method params
}
答案 1 :(得分:6)
最简单的方式
override func viewDidLoad() {
super.viewDidLoad()
testFunc(index: 2, callback: { str in
print(str)
})
}
func testFunc(index index: Int, callback: (String) -> Void) {
callback("The number is \(index)")
}
答案 2 :(得分:0)
你的问题在于:
var timer = NSTimer()
您无法以这种方式实例化NSTimer。它具有为您生成对象的类方法。在这种情况下解决问题的最简单方法是使定义变得懒惰,如下所示:
lazy var timer = NSTimer()
这样,直到正确设置它的启动方法,实际上才会触及定时器的值。注意:这可能是一种更安全的方法。