Home > database >  Unrecognized selector error from calling a function on a timer
Unrecognized selector error from calling a function on a timer

Time:09-01

New to Objective C and trying to store past gps data using a timer. My code is as follows ('data' is declared earlier in the class as an instance of a struct with the multiple arrays you see):

var synchronizer = Timer.scheduledTimer(timeInterval: 1.0, target: timerClass.self, selector: #selector(cycle), userInfo: nil, repeats: true)
    
@objc func cycle()
{
    data.timeArray.insert(Date.init(), at: 0)
    if (data.timeArray.count > 30) {
        data.timeArray = data.timeArray.dropLast(data.timeArray.count - 30)
    }
    loc.requestLocation()
    let dateFormatter = DateFormatter()
    var ts = "Time: ["
    for time in data.timeArray {
        ts.append(" "   dateFormatter.string(from: time)   ",")
    }
    ts.append("]")
    timeString.text = ts
    var ss = "Speed: ["
    for loc in data.speedArray {
        ss.append(" "   String(format:"%.0f",loc.speed*2.237)   ",")
    }
    ss.append("]")
    timeString.text = ss
}

As soon as the timer actually runs I get this error: [projectName.timerClass cycle]: unrecognized selector sent to class 0x1032fba38

I have to assume that the issue is with my declaration of 'synchronizer', but I can't find any differing instructions for Objective C.

CodePudding user response:

I assume the code takes place in the scope of a class named timerClass, so surrounding looks something like this:

class timerClass {

    var synchronizer = Timer.scheduledTimer(timeInterval: 1.0, target: timerClass.self, selector: #selector(cycle), userInfo: nil, repeats: true)
    ...
}

Since you try to access self from the context of default property value, the compiler apparently suggested to switch to timerClass.self, however that is not what you want to access here, because it refers to the class, not its instance.

As long as you need to refer to self, you should initialise your property lazily:

lazy var synchronizer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(cycle), userInfo: nil, repeats: true)

Or inside of a constructor:

var synchronizer: Timer

init() {
    synchronizer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(cycle), userInfo: nil, repeats: true)
}
 

CodePudding user response:

You appear to be trying to send timer event to a class, rather than to an instance. The target needs to be an instance of timerClass (which I hope is spelled "TimerClass" with a leading capital as classes should be).

  • Related