I have a simple class which init
method takes an Int and a callback function.
我有一个简单的类,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)
}
}
Then in the ViewController I have this:
然后在ViewController中我有这个:
var timer = Timer(duration: 5, handler: displayTimeRemaining)
func displayTimeRemaining(counter: Int) -> Void {
println(counter)
}
This doesn't work, I get the following:
这不起作用,我得到以下内容:
'Int' is not a subtype of 'SecondViewController'
'Int'不是'SecondViewController'的子类型
Edit 1: Adding full code.
编辑1:添加完整代码。
Timer.swift
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
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)
}
}
I just started with Swift so I'm very green. How are you supposed to pass callbacks? I've looked at examples and this should be working I think. Is my class defined incorrectly for the way I'm passing the callback?
我刚开始使用Swift,所以我非常环保。你打算如何通过回调?我看了一些例子,我认为这应该是有效的。我的类是否因我传递回调的方式而被错误地定义了?
Thanks
谢谢
3 个解决方案
#1
15
Ok, now with the full code I was able to replicate your issue. I'm not 100% sure what the cause is but I believe it has something to do with referencing a class method (displayTimeRemaining) before the class was instantiated. Here are a couple of ways around this:
好的,现在有了完整的代码我能够复制你的问题。我不是100%确定原因是什么,但我认为它与在实例化类之前引用类方法(displayTimeRemaining)有关。以下是几种解决方法:
Option 1: Declare the handler method outside of the SecondViewController class:
选项1:在SecondViewController类之外声明处理程序方法:
func displayTimeRemaining(counter: Int) -> Void {
println(counter)
}
class SecondViewController: UIViewController {
// ...
var timer = Timer(duration: 5, handler: displayTimeRemaining)
Option 2: Make displayTimeRemaining into a type method by adding the class keyword to function declaration.
选项2:通过将class关键字添加到函数声明中,使displayTimeRemaining成为一个类型方法。
class SecondViewController: UIViewController {
var timer: Timer = Timer(duration: 5, handler: SecondViewController.displayTimeRemaining)
class func displayTimeRemaining(counter: Int) -> Void {
println(counter)
}
Option 3: I believe this will be the most inline with Swift's way of thinking - use a closure:
选项3:我相信这将是最符合Swift思维方式的内容 - 使用闭包:
class SecondViewController: UIViewController {
var timer: Timer = Timer(duration: 5) {
println($0) //using Swift's anonymous method params
}
#2
4
Simplest way
最简单的方法
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)")
}
#3
0
Your problem is in the line:
你的问题在于:
var timer = NSTimer()
You cannot instantiate an NSTimer in this way. It has class methods that generate an object for you. The easiest way to get around the problem in this case is to make the definition lazy, like so:
您无法以这种方式实例化NSTimer。它具有为您生成对象的类方法。在这种情况下解决问题的最简单方法是使定义变得懒惰,如下所示:
lazy var timer = NSTimer()
In this way the value for timer won't actually be touched until the start method which sets it up properly. NOTE: There is probably a safer way to do this.
以这种方式,直到正确设置它的启动方法,实际上不会触及定时器的值。注意:这可能是一种更安全的方法。
#1
15
Ok, now with the full code I was able to replicate your issue. I'm not 100% sure what the cause is but I believe it has something to do with referencing a class method (displayTimeRemaining) before the class was instantiated. Here are a couple of ways around this:
好的,现在有了完整的代码我能够复制你的问题。我不是100%确定原因是什么,但我认为它与在实例化类之前引用类方法(displayTimeRemaining)有关。以下是几种解决方法:
Option 1: Declare the handler method outside of the SecondViewController class:
选项1:在SecondViewController类之外声明处理程序方法:
func displayTimeRemaining(counter: Int) -> Void {
println(counter)
}
class SecondViewController: UIViewController {
// ...
var timer = Timer(duration: 5, handler: displayTimeRemaining)
Option 2: Make displayTimeRemaining into a type method by adding the class keyword to function declaration.
选项2:通过将class关键字添加到函数声明中,使displayTimeRemaining成为一个类型方法。
class SecondViewController: UIViewController {
var timer: Timer = Timer(duration: 5, handler: SecondViewController.displayTimeRemaining)
class func displayTimeRemaining(counter: Int) -> Void {
println(counter)
}
Option 3: I believe this will be the most inline with Swift's way of thinking - use a closure:
选项3:我相信这将是最符合Swift思维方式的内容 - 使用闭包:
class SecondViewController: UIViewController {
var timer: Timer = Timer(duration: 5) {
println($0) //using Swift's anonymous method params
}
#2
4
Simplest way
最简单的方法
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)")
}
#3
0
Your problem is in the line:
你的问题在于:
var timer = NSTimer()
You cannot instantiate an NSTimer in this way. It has class methods that generate an object for you. The easiest way to get around the problem in this case is to make the definition lazy, like so:
您无法以这种方式实例化NSTimer。它具有为您生成对象的类方法。在这种情况下解决问题的最简单方法是使定义变得懒惰,如下所示:
lazy var timer = NSTimer()
In this way the value for timer won't actually be touched until the start method which sets it up properly. NOTE: There is probably a safer way to do this.
以这种方式,直到正确设置它的启动方法,实际上不会触及定时器的值。注意:这可能是一种更安全的方法。