instance error from unreconized selector with #objc [duplicate] - swift

This question already has answers here:
Swift 4 Timer Crashes with NSException
(3 answers)
Timer on swift not working
(1 answer)
Closed 3 years ago.
when i run my aplication i get this error
Nick[66720:3658939] -[_SwiftValue function1]: unrecognized selector sent to instance
i tried moving out of the class and it says
only protocol member can be there
import Cocoa
class mymainclass: NSObject, NSApplicationDelegate{
var mytimer = Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(function1), userInfo: nil, repeats: true)
func applicationDockMenu(_ sender: NSApplication) -> NSMenu? {
return dockMenu
}
#objc func function1(){
print(“function1 test”)
}
}

You are trying to use self on the class level, this way it is not referring to your created class instance.
Instead, you can create the timer after your class instance is created.
Inside the class constructor, there self will be referring to what you are expecting
class Mymainclass: NSObject, NSApplicationDelegate{
var mytimer: Timer?
override init() {
super.init()
self.mytimer = Timer.scheduledTimer(timeInterval: 0.2, target: self, selector: #selector(function1), userInfo: nil, repeats: true)
}
#objc func function1(){
print("function1 test")
}
}
Note: Class names start with Capital letter

Related

Swift timer method terminates the app early with SIGABRT error

Below is my code for having a timer change a variable from 0 to 1, which results in a SIGABRT error when the timer tries to fire:
var timerToggle = 0
let timer = Timer.scheduledTimer(timeInterval: 5.0, target: self, selector: #selector(fireTimer), userInfo: nil, repeats: false)
#objc func fireTimer() {
timerToggle = 1
}
I know others who've had this problem seem to solve it by placing the timer declaration within the override func viewDidLoad() function but whenever I do that it gives me the following error
"Initialization of immutable value 'timer' was never used; consider replacing with assignment to '_' or removing it."
Any help would be greatly appreciated
"Initialization of immutable value 'timer' was never used; consider
replacing with assignment to '_' or removing it."
This is just a warning not an error. You can still go ahead and initialise timer in viewDidLoad.
If it is needed to activate once-fired timer in viewDidLoad, it should look somehow like the following
class MyController: UIViewController {
var timerToggle = 0
private var timer: Timer?
deinit {
timer?.invalidate()
}
#objc func fireTimer() {
timerToggle = 1
timer = nil
}
override func viewDidLoad() {
super.viewDidLoad()
timer = Timer.scheduledTimer(timeInterval: 5.0, target: self,
selector: #selector(fireTimer), userInfo: nil, repeats: false)
}
}
If you are not going to access the timer anymore simply add below to viewDidLoad
_ = Timer.scheduledTimer(timeInterval: 5.0,
target: self,
selector: #selector(fireTimer),
userInfo: nil,
repeats: false)

Error Type 'MyClass" has no Member on "onTimer'

I copied the following code from Github in order to get more experience with playground but I keep getting an error
Type 'MyClass" has no Member on "onTimer'!
I tried to look at previous messages to find a solution, unfortunately, I couldn't. If possible can you please help me to solve it. Thanks
import UIKit
class MyClass {
func startTimer() {
Timer.scheduledTimerWithTimeInterval(2, target: self, selector: #selector(MyClass.onTimer(_:)), userInfo: nil, repeats: false)
}
#objc func onTimer(timer:Timer!) {
print("Timer here")
}
}
var anInstance = MyClass()
anInstance.startTimer()
CFRunLoopRun()
Change to ( Swift 4.2 )
Timer.scheduledTimer(timeInterval:2, target: self, selector: #selector(onTimer(_:)), userInfo: nil, repeats: true)
#objc func onTimer(_ timer:Timer)
Verify also if you need repeats: true) instead of repeats: false)

Unrecognized selector sent to class when using NSTimer in Swift; NSInvalidArgumentException

I'm trying to use an NSTimer to run a function at a certain interval, but every time it runs the program crashes with an exception:
+[Project.Class updateLabel]: unrecognized selector sent to class...
Terminating app due to uncaught exception "NSInvalidArgumentException".
The code is as follows:
class SecondViewController: UIViewController {
// MARK: Properties
override func viewDidLoad() {
super.viewDidLoad()
do {
try updateLabel()
try startTimer()
}
catch{
self.showAlert()
}
}
#IBOutlet weak var i2cLabel: UILabel!
// MARK: Actions
func startTimer() throws {
_ = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("updateLabel"), userInfo: nil, repeats: true)
}
func showAlert() {
}
func updateLabel() throws {
}
}
If I comment out the NSTimer line, the program compiles and runs just fine.
Note that updateLabel(), the selector function, takes no arguments so calling it as a selector without a colon suffix should work. This seems to be unique to this problem.
Try update your code to:
override func viewDidLoad() {
super.viewDidLoad()
do {
updateLabel()
try startTimer()
}
catch{
self.showAlert()
}
}
// MARK: Actions
func startTimer() throws {
_ = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("updateLabel"), userInfo: nil, repeats: true)
}
func showAlert() {
}
func updateLabel() {
}
It seems that: NSTimer don't know call a function throws. So it will crash.
I have tried to find some official or some article describe about it. But sad that I can't find now.
You can reference to this question: Reference
Hope this help!

Is it possible to set a struct as target for NSTimer

I am trying to set scheduledTimerWithTimeInterval inside a struct but I keep getting the error Cannot invoke scheduledTimerWithTimeInterval with argument list of type. When I change the struct to a class it works fine.
My question is it possible to set a struct as the target of a NSTimer? The API says it should be of type AnyObject
struct MyTimer{
init() {
let timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("timer"), userInfo: nil, repeats: true)
}
}
and
class MyTimer{
init() {
let timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: Selector("timer"), userInfo: nil, repeats: true)
}
}
EDIT: It seems that for a class to be the target of a scheduledTimer it has to inherit from NSObject first. A struct could never to that.

Using NSTimer in swift playground [duplicate]

This question already has answers here:
How do I run Asynchronous callbacks in Playground
(8 answers)
Closed 7 years ago.
I'd like to know how to use an NSTimer inside a Swift Playground. This question has been asked before, but none of the answers actually answered the question.
Here's my Playground code:
import Foundation
class MyClass {
func startTimer() {
NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "onTimer:", userInfo: nil, repeats: true)
}
func onTimer(timer:NSTimer!) {
println("Timer here")
}
}
var anInstance = MyClass()
anInstance.startTimer()
Instantiating NSTimer with scheduledTimerWithTimeInterval creates the timer and schedules it on the current run loop.
But the method onTimer is never called. Why?
First of all, your onTimer method have to be declared as #objc, or NSTimer cannot find that.
As for your question, it's because you haven't started the run loop.
To do that, CFRunLoopRun() is the simplest solution I think.
import Foundation
class MyClass {
func startTimer() {
NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "onTimer:", userInfo: nil, repeats: true)
}
#objc func onTimer(timer:NSTimer!) {
println("Timer here")
}
}
var anInstance = MyClass()
anInstance.startTimer()
CFRunLoopRun() // <-- HERE!
For the sake of completeness, as #MartinR metioned in the comment, you can also use XCPSetExecutionShouldContinueIndefinitely()
import Foundation
import XCPlayground
XCPSetExecutionShouldContinueIndefinitely()
class MyClass {
func startTimer() {
NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector: "onTimer:", userInfo: nil, repeats: true)
}
#objc func onTimer(timer:NSTimer!) {
println("Timer here")
}
}
var anInstance = MyClass()
anInstance.startTimer()
In this case the Playground runs only seconds specified in the Timeline: