I have a simple class which init
method takes an Int and a callback function.
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:
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'
Edit 1: Adding full code.
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) } }
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?
Thanks
Every function in Swift has a type, consisting of the function's parameter types and return type. You can use this type like any other type in Swift, which makes it easy to pass functions as parameters to other functions, and to return functions from functions.
A callback function is a function passed into another function as an argument, which is then invoked inside the outer function to complete some kind of routine or action. The above example is a synchronous callback, as it is executed immediately.
generically, a delegate is an object used to access a method external to the object owning the method, while a callback is a variable that holds a delegate. in C#, the terms are used interchangeably.
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:
Option 1: Declare the handler method outside of the SecondViewController class:
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.
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:
class SecondViewController: UIViewController { var timer: Timer = Timer(duration: 5) { println($0) //using Swift's anonymous method params }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With