spacecash21
spacecash21

Reputation: 1331

Swift selector - unrecognized selector sent to instance

I have a function:

func runRockRotation(rockSprite: SKSpriteNode){
    startRockRotationAnimation(rockSprite, isRock: true)
}

When I call it like this:

runRockRotation(rock)

it works, but I can't seem to be able to put it inside a NSTimer selector.

var timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "runRockRotation:", userInfo: rock, repeats: false)

Read a lot of forums, tried this:

var timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "runRockRotation()", userInfo: rock, repeats: false)
var timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "runRockRotation(_)", userInfo: rock, repeats: false)
var timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "runRockRotation", userInfo: rock, repeats: false)

Also, tried without rock, using nil, but nothing seems to work.

Every time I get:

2015-04-10 15:49:03.830 Meh[1640:218030] -[__NSCFTimer runAction:completion:]: unrecognized selector sent to instance 0x174166840
2015-04-10 15:49:03.832 Meh[1640:218030] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFTimer runAction:completion:]: unrecognized selector sent to instance 0x174166840'

How do I call my function in a selector with a parameter? I know how to do that in Objective C, but can't seem to do it in Swift. All help will be appreciated.

Upvotes: 5

Views: 2624

Answers (2)

Noam
Noam

Reputation: 628

Also helps to make sure the target object (self in your case) is a subclass of NSObject

var timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: <THIS MUST BE NSOBJECT SUBCLASS>, selector: "runRockRotation:", userInfo: rock, repeats: false)

Upvotes: 2

Paulw11
Paulw11

Reputation: 114773

Check the documentation for scheduledTimerWithTimeInterval

You will see that

The selector should have the following signature: timerFireMethod: (including a colon to indicate that the method takes an argument).

The timer passes itself as the argument, thus the method would adopt the following pattern: - (void)timerFireMethod:(NSTimer *)timer

Your function doesn't match this pattern, so the appropriate selector cannot be found.

Use something like -

func runRockRotationForTimer(_ timer: NSTimer){
    self.runRockRotation(timer.userInfo as? SKSpriteNode)
    timer.invalidate();
}

and schedule it using

var timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: "runRockRotationForTimer:", userInfo: rock, repeats: false)

Upvotes: 8

Related Questions