By Arbitur

2014-06-03 05:21:43 8 Comments

I'm trying to create an NSTimer in Swift but I'm having some trouble.

NSTimer(timeInterval: 1, target: self, selector: test(), userInfo: nil, repeats: true)

test() is a function in the same class.

I get an error in the editor:

Could not find an overload for 'init' that accepts the supplied arguments

When I change selector: test() to selector: nil the error disappears.

I've tried:

  • selector: test()
  • selector: test
  • selector: Selector(test())

But nothing works and I can't find a solution in the references.


@Mustajab Haider 2017-02-28 06:41:12

For swift 3

let timer = Timer.scheduledTimer(timeInterval: 0.01, target: self, selector: #selector(self.test), userInfo: nil, repeats: true)

Function declaration In same class:

@objc func test()
    // my function

@Michael Peterson 2014-07-12 19:33:11

It may be useful to note where you setup the control that triggers the action matters.

For example, I have found that when setting up a UIBarButtonItem, I had to create the button within viewDidLoad or else I would get an unrecognized selector exception.

override func viewDidLoad() {

    // add button
    let addButton = UIBarButtonItem(image: UIImage(named: "746-plus-circle.png"), style: UIBarButtonItemStyle.Plain, target: self, action: Selector("addAction:"))
    self.navigationItem.rightBarButtonItem = addButton

func addAction(send: AnyObject?) {     

@Mahesh Chaudhari 2018-11-19 10:26:01

Selector in Swift 4:

button.addTarget(self, action: #selector(buttonTapped(sender:)), for: UIControlEvents.touchUpInside)

@CrazyPro007 2018-05-19 17:03:46

For Swift 3

//Sample code to create timer

Timer.scheduledTimer(timeInterval: 1, target: self, selector: (#selector(updateTimer)), userInfo: nil, repeats: true)

timeInterval:- Interval in which timer should fire like 1s, 10s, 100s etc. [Its value is in secs]
target:- function which pointed to class. So here I am pointing to current class.
selector:- function that will execute when timer fires.

func updateTimer(){

repeats:- true/false specifies that timer should call again n again.

@Krunal 2017-06-09 13:43:39

Swift 4.1
With sample of tap gesture

let gestureRecognizer = UITapGestureRecognizer()
gestureRecognizer.addTarget(self, action: #selector(self.dismiss(completion:)))

// Use destination 'Class Name' directly, if you selector (function) is not in same class.
//gestureRecognizer.addTarget(self, action: #selector(DestinationClass.dismiss(completion:)))

@objc func dismiss(completion: (() -> Void)?) {
      self.dismiss(animated: true, completion: completion)

See Apple's document for more details about: Selector Expression

@Fogmeister 2017-06-09 13:58:53

Please stop doing this. It helps no one. How is this any different from Swift 3.1? And why did you think it necessary to add another answer to this when it already has about 20 answers?

@Krunal 2017-06-09 13:59:53

calling selector is different in swift 4. Try these answers in swift 4 and see. None these will work without editing. Please do not mark any statement as spam without ensuring its impotance

@Fogmeister 2017-06-09 14:00:57

So is there any reason you couldn't edit the existing, accepted answer? It would make it actually useful rather than adding on the end of a long list of answers. The "Edit" button is there for a reason.

@Fogmeister 2017-06-09 14:02:37

Also, which part of this is different from Swift 3?

@Unome 2017-09-26 15:33:15

You have to add the objc tag to any selectors for Swift 4. This is the correct answer. And your not supposed to edit other people's answers to change their meaning. @Krunal is totally right.

@Mike 2018-02-05 17:25:33

I have a question about this answer. I understand the need for the @objc in the declaration. My question is about the use of `self.dismiss(completion:))) rather than a class type identifier i.e. MyCustomUIView.dismiss(completion:))). All the docs I can find in swift-evolution appear to follow the type-id format suggested in swift-evolution/.../proposals/0022-objc-selectors. Is using the iVar 'self' now required or that that a convenience you've adopted?

@pravin salame 2014-10-15 07:27:18

Swift 4.0

you create the Selector like below.

1.add the event to a button like:

button.addTarget(self, action: #selector(clickedButton(sender:)), for: UIControlEvents.touchUpInside)

and the function will be like below:

@objc func clickedButton(sender: AnyObject) {


@Vahid Amiri 2018-01-27 15:49:24

You forgot to put @objc before func which is required in Swift 4.

@Kyle Clegg 2016-04-06 16:06:21

Swift 2.2+ and Swift 3 Update

Use the new #selector expression, which eliminates the need to use string literals making usage less error-prone. For reference:




See also: Swift Evolution Proposal

Note (Swift 4.0):

If using #selectoryou would need to mark the function as @objc


@objc func something(_ sender: UIButton)

@rickster 2014-06-03 05:27:11

Swift itself doesn't use selectors — several design patterns that in Objective-C make use of selectors work differently in Swift. (For example, use optional chaining on protocol types or is/as tests instead of respondsToSelector:, and use closures wherever you can instead of performSelector: for better type/memory safety.)

But there are still a number of important ObjC-based APIs that use selectors, including timers and the target/action pattern. Swift provides the Selector type for working with these. (Swift automatically uses this in place of ObjC's SEL type.)

In Swift 2.2 (Xcode 7.3) and later (including Swift 3 / Xcode 8 and Swift 4 / Xcode 9):

You can construct a Selector from a Swift function type using the #selector expression.

let timer = Timer(timeInterval: 1, target: object,
                  selector: #selector(MyClass.test),
                  userInfo: nil, repeats: false)
button.addTarget(object, action: #selector(MyClass.buttonTapped),
                 for: .touchUpInside)
             with: button, with: otherButton)

The great thing about this approach? A function reference is checked by the Swift compiler, so you can use the #selector expression only with class/method pairs that actually exist and are eligible for use as selectors (see "Selector availability" below). You're also free to make your function reference only as specific as you need, as per the Swift 2.2+ rules for function-type naming.

(This is actually an improvement over ObjC's @selector() directive, because the compiler's -Wundeclared-selector check verifies only that the named selector exists. The Swift function reference you pass to #selector checks existence, membership in a class, and type signature.)

There are a couple of extra caveats for the function references you pass to the #selector expression:

  • Multiple functions with the same base name can be differentiated by their parameter labels using the aforementioned syntax for function references (e.g. insertSubview(_:at:) vs insertSubview(_:aboveSubview:)). But if a function has no parameters, the only way to disambiguate it is to use an as cast with the function's type signature (e.g. foo as () -> () vs foo(_:)).
  • There's a special syntax for property getter/setter pairs in Swift 3.0+. For example, given a var foo: Int, you can use #selector(getter: or #selector(setter:

General notes:

Cases where #selector doesn't work, and naming: Sometimes you don't have a function reference to make a selector with (for example, with methods dynamically registered in the ObjC runtime). In that case, you can construct a Selector from a string: e.g. Selector("dynamicMethod:") — though you lose the compiler's validity checking. When you do that, you need to follow ObjC naming rules, including colons (:) for each parameter.

Selector availability: The method referenced by the selector must be exposed to the ObjC runtime. In Swift 4, every method exposed to ObjC must have its declaration prefaced with the @objc attribute. (In previous versions you got that attribute for free in some cases, but now you have to explicitly declare it.)

Remember that private symbols aren't exposed to the runtime, too — your method needs to have at least internal visibility.

Key paths: These are related to but not quite the same as selectors. There's a special syntax for these in Swift 3, too: e.g. chris.valueForKeyPath(#keyPath(Person.friends.firstName)). See SE-0062 for details. And even more KeyPath stuff in Swift 4, so make sure you're using the right KeyPath-based API instead of selectors if appropriate.

You can read more about selectors under Interacting with Objective-C APIs in Using Swift with Cocoa and Objective-C.

Note: Before Swift 2.2, Selector conformed to StringLiteralConvertible, so you might find old code where bare strings are passed to APIs that take selectors. You'll want to run "Convert to Current Swift Syntax" in Xcode to get those using #selector.

@Arbitur 2014-06-03 05:36:32

Putting a string with the function name worked, NSSelectorFromString() works also.

@user1040049 2014-06-03 20:32:37

I'd like to mention that while "Interacting with Objective-C APIs" is on the website, it is NOT in 'The Swift Programming Language' book.

@Daniel Schlaug 2014-07-06 14:06:07

This should probably mention that the selector needs a ":" at the end if it takes an argument. (E.g. test() -> "test" & test(this:String) -> "test:")

@jpittman 2014-07-29 20:59:52

Heads up: the third argument in the "addTarget" statement (forControlEvents) needs a period ( . ) in front of TouchUpInside.

@JMFR 2014-10-28 18:13:01

It should also be pointed out that the Cocoa frameworks expect an Objective-C style method name. If your method takes an argument you will need a ':' if it takes 2 arguments, size:andShape:, if the first argument is named you may need a With, i.e. initWithData: for func init(Data data: NSData)

@cynistersix 2014-11-12 22:56:39

I would use the "@objc func" answer below personally.

@yo.ian.g 2014-12-13 18:59:29

Is there anyway to add validation around passing the "selector" as a string? IE compiler warn us when we misspell, etc.

@kostyl 2015-02-18 20:30:54

Is it true way to use String as selector in Swift while in ObjC runtime it is decleared as typedef struct objc_selector *SEL ?

@FeifanZ 2015-02-25 17:05:33

Also note that the selected method cannot be private, otherwise it will not be able to find the method.

@confile 2015-03-13 12:34:28

@rickster is there a way that the selector in Swift can checked at compile time?

@kelin 2015-05-29 14:34:07

I must add that selector function should be declared without private modifier.

@rickster 2015-06-29 17:24:01

@confile: belated follow up: No, but that's little different from ObjC... The warning you get from passing garbage to @selector() only checks whether that selector is known to your project, not whether it's valid to call on a specific target.

@Stuart P. 2015-10-28 20:07:49

If I attempt to use just "selectorNameHere" swift now throws an error for me, using Selector("selectorNameHere") works. This works: item.rightBarButtonItem = UIBarButtonItem(image: menuIcon, style: UIBarButtonItemStyle.Plain, target: self, action: Selector("showSideMenu"))

@matt 2016-03-20 02:06:05

@rickster For Swift 2.2, they might like a link to my answer here:

@Matthew Seaman 2016-03-29 22:56:41

In Swift 2.2, it looks like the method may be private, but if it is then it needs to have the @objc attribute, even if it subclasses NSObject.

@Umair Aamir 2017-04-11 11:52:32

How can I use selector inside a struct. It gives me error that "@objc can only be used with members of classes, @objc protocols, and concrete extensions of classes"

@John Lee 2016-06-01 03:42:27

// for swift 2.2
// version 1
buttton.addTarget(self, action: #selector(ViewController.tappedButton), forControlEvents: .TouchUpInside)
buttton.addTarget(self, action: #selector(ViewController.tappedButton2(_:)), forControlEvents: .TouchUpInside)

// version 2
buttton.addTarget(self, action: #selector(self.tappedButton), forControlEvents: .TouchUpInside)
buttton.addTarget(self, action: #selector(self.tappedButton2(_:)), forControlEvents: .TouchUpInside)

// version 3
buttton.addTarget(self, action: #selector(tappedButton), forControlEvents: .TouchUpInside)
buttton.addTarget(self, action: #selector(tappedButton2(_:)), forControlEvents: .TouchUpInside)

func tappedButton() {

func tappedButton2(sender: UIButton) {
  print("tapped 2")

// swift 3.x
button.addTarget(self, action: #selector(tappedButton(_:)), for: .touchUpInside)

func tappedButton(_ sender: UIButton) {
  // tapped

button.addTarget(self, action: #selector(tappedButton(_:_:)), for: .touchUpInside)

func tappedButton(_ sender: UIButton, _ event: UIEvent) {
  // tapped

@nyxee 2017-07-19 22:24:39

it would have been nicer and more educative if u had an example taking two or three arguments for Swift3 or Swift4 too. Thanks.

@LukeSideWalker 2016-09-16 18:24:29

Since Swift 3.0 is published, it is even a little bit more subtle to declare a targetAction appropriate

class MyCustomView : UIView {

    func addTapGestureRecognizer() {

        // the "_" is important
        let tapGestureRecognizer = UITapGestureRecognizer(target: self, action: #selector(MyCustomView.handleTapGesture(_:)))
        tapGestureRecognizer.numberOfTapsRequired = 1

    // since Swift 3.0 this "_" in the method implementation is very important to 
    // let the selector understand the targetAction
    func handleTapGesture(_ tapGesture : UITapGestureRecognizer) {

        if tapGesture.state == .ended {
            print("TapGesture detected")

@sschunara 2016-03-17 06:48:18

When using performSelector()

/addtarget()/NStimer.scheduledTimerWithInterval() methods your method (matching the selector) should be marked as

For Swift 2.0:
        self.performSelector(“performMethod”, withObject: nil , afterDelay: 0.5)

    btnHome.addTarget(self, action: “buttonPressed:", forControlEvents: UIControlEvents.TouchUpInside)

     NSTimer.scheduledTimerWithTimeInterval(0.5, target: self, selector : “timerMethod”, userInfo: nil, repeats: false)


@objc private func performMethod() {
@objc private func buttonPressed(sender:UIButton){
@objc private func timerMethod () {

For Swift 2.2, you need to write '#selector()' instead of string and selector name so the possibilities of spelling error and crash due to that will not be there anymore. Below is example

self.performSelector(#selector(MyClass.performMethod), withObject: nil , afterDelay: 0.5)

@Swift Developer 2016-05-20 11:31:33

Using #selector will check your code at compile time to make sure the method you want to call actually exists. Even better, if the method doesn’t exist, you’ll get a compile error: Xcode will refuse to build your app, thus banishing to oblivion another possible source of bugs.

override func viewDidLoad() {

        navigationItem.rightBarButtonItem =
            UIBarButtonItem(barButtonSystemItem: .Add, target: self,
                            action: #selector(addNewFireflyRefernce))

    func addNewFireflyReference() {
        gratuitousReferences.append("Curse your sudden but inevitable betrayal!")

@cynistersix 2016-02-14 17:58:04

I found many of these answers to be helpful but it wasn't clear how to do this with something that wasn't a button. I was adding a gesture recognizer to a UILabel in swift and struggled so here's what I found worked for me after reading everything above:

let tapRecognizer = UITapGestureRecognizer(
            target: self,
            action: "labelTapped:")

Where the "Selector" was declared as:

func labelTapped(sender: UILabel) { }

Note that it is public and that I am not using the Selector() syntax but it is possible to do this as well.

let tapRecognizer = UITapGestureRecognizer(
            target: self,
            action: Selector("labelTapped:"))

@Martin Cazares 2014-07-13 05:31:52

Just in case somebody else have the same problem I had with NSTimer where none of the other answers fixed the issue, is really important to mention that, if you are using a class that do not inherits from NSObject either directly or deep in the hierarchy(e.g. manually created swift files), none of the other answers will work even when is specified as follows:

let timer = NSTimer(timeInterval: 1, target: self, selector: "test", 
                    userInfo: nil, repeats: false)
func test () {}

Without changing anything else other than just making the class inherit from NSObject I stopped getting the "Unrecognized selector" Error and got my logic working as expected.

@eharo2 2014-07-22 18:47:33

The issue with this alternative is that you can´t change a class (let´s say ViewController) to inherit from NSObject, given that you need the ViewController class implemented stuff (e.g. viewDidLoad()). Any idea how to call a Swift function within a ViewController using NSTimer?... e

@Martin Cazares 2014-07-22 19:10:21

UIViewController already inherits from NSObject, most classes exposed by the SDK do, this example is for your own created classes that require NSTimer functionality...

@Rob Sanders 2015-04-10 18:08:14

For future readers, I found that I experienced a problem and was getting an unrecognised selector sent to instance error that was caused by marking the target func as private.

The func MUST be publicly visible to be called by an object with a reference to a selector.

@apouche 2015-10-28 10:40:39

it doesn't have to be public you can still keep the method private but add objc before it's declaration. Ex: @objc private func foo() { ... then you can use "foo" as a selector as much you like

@NAlexN 2017-01-30 14:15:30

dynamic func foo() { ... } also works

@Sajjon 2017-04-06 08:27:14

It can also be internal, thus not specifying any access modifier. I often use this pattern: //MARK: - Selector Methods\n extension MyController {\n func buttonPressed(_ button: UIButton) {

@user3771857 2014-06-24 15:23:39

Also, if your (Swift) class does not descend from an Objective-C class, then you must have a colon at the end of the target method name string and you must use the @objc property with your target method e.g.

var rightButton = UIBarButtonItem(title: "Title", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("method"))

@objc func method() {
    // Something cool here   

otherwise you will get a "Unrecognised Selector" error at runtime.

@Yevhen Dubinin 2014-12-01 00:31:46

1. selectors w/ a colon must take an argument 2. according to Apple docs timer's actions should take NSTimer argument 3. Selector keyword is not mandatory. So in this case signature must be @objc func method(timer: NSTimer) {/*code*/}

@Mike Taverne 2015-02-05 19:03:34

@objc worked for me. I didn't need to include timer: NSTimer in my method signature for it to be called.

@Thar Htet 2014-10-14 04:49:05

Change as a simple string naming in the method calling for selector syntax

var timer1 : NSTimer? = nil
timer1= NSTimer(timeInterval: 0.1, target: self, selector: Selector("test"), userInfo: nil, repeats: true)

After that, type func test().

@Scooter 2014-08-07 15:29:05

If you want to pass a parameter to the function from the NSTimer then here is your solution:

var somethingToPass = "It worked"

let timer = NSTimer.scheduledTimerWithTimeInterval(0.01, target: self, selector: "tester:", userInfo: somethingToPass, repeats: false)

func tester(timer: NSTimer)
    let theStringToPrint = timer.userInfo as String

Include the colon in the selector text (tester:), and your parameter(s) go in userInfo.

Your function should take NSTimer as a parameter. Then just extract userInfo to get the parameter that passed.

@iOS-Coder 2015-07-05 12:19:20

I was using NSTimer(0.01, target: self, ...) which did NOT work, whereas using NSTimer.scheduledTimerWithTimeInterval(0.01, ..) DID work!? Strange but thanks @Scooter for you answer!

@David Ganster 2015-10-05 21:30:54

@iOS-Coder just creating a timer with the initialiser does not add it to a runloop, whereas scheduledTimerWith... automatically adds it to the current runloop - so there is no strange behaviour here at all ;)

@iOS-Coder 2015-10-06 22:27:44

@David thanks for your suggestion. I guess my misunderstanding should belong in either STFW or RTFA (Read The API) category?

@David Ganster 2015-10-07 09:14:20

Don't worry about it, no one can be expected to read the documentation about every single method in every API ;)

@Renish Dadhaniya 2014-07-19 06:26:29

Create Refresh control using Selector method.   
    var refreshCntrl : UIRefreshControl!
    refreshCntrl = UIRefreshControl()
    refreshCntrl.tintColor = UIColor.whiteColor()
    refreshCntrl.attributedTitle = NSAttributedString(string: "Please Wait...")
    refreshCntrl.addTarget(self, action:"refreshControlValueChanged", forControlEvents: UIControlEvents.ValueChanged)

//Refresh Control Method

func refreshControlValueChanged(){


@Daxesh Nagar 2014-07-11 19:14:51

you create the Selector like below.

    title: "Some Title",
    style: UIBarButtonItemStyle.Done,
    target: self,
    action: "flatButtonPressed"


flatButton.addTarget(self, action: "flatButtonPressed:", forControlEvents: UIControlEvents.TouchUpInside)

Take note that the @selector syntax is gone and replaced with a simple String naming the method to call. There’s one area where we can all agree the verbosity got in the way. Of course, if we declared that there is a target method called flatButtonPressed: we better write one:

func flatButtonPressed(sender: AnyObject) {

set the timer:

    var timer = NSTimer.scheduledTimerWithTimeInterval(1.0, 
                    target: self, 
                    selector: Selector("flatButtonPressed"), 
                    userInfo: userInfo, 
                    repeats: true)
    let mainLoop = NSRunLoop.mainRunLoop()  //1
    mainLoop.addTimer(timer, forMode: NSDefaultRunLoopMode) //2 this two line is optinal

In order to be complete, here’s the flatButtonPressed

func flatButtonPressed(timer: NSTimer) {

@winklerrr 2018-03-21 15:58:36

Do you have any source for "Take note that the @selector syntax is gone"?

@Jon Tsiros 2014-06-05 05:43:45

Selectors are an internal representation of a method name in Objective-C. In Objective-C "@selector(methodName)" would convert a source-code method into a data type of SEL. Since you can't use the @selector syntax in Swift (rickster is on point there), you have to manually specify the method name as a String object directly, or by passing a String object to the Selector type. Here is an example:

var rightBarButton = UIBarButtonItem(
    title: "Logout", 
    style: UIBarButtonItemStyle.Plain, 
    target: self, 


var rightBarButton = UIBarButtonItem(
    title: "Logout", 
    style: UIBarButtonItemStyle.Plain, 
    target: self, 

@Oscar Swanros 2014-06-03 05:31:39

Here's a quick example on how to use the Selector class on Swift:

override func viewDidLoad() {

    var rightButton = UIBarButtonItem(title: "Title", style: UIBarButtonItemStyle.Plain, target: self, action: Selector("method"))
    self.navigationItem.rightBarButtonItem = rightButton

func method() {
    // Something cool here   

Note that if the method passed as a string doesn't work, it will fail at runtime, not compile time, and crash your app. Be careful

@Lena Bru 2014-06-04 22:47:50

which is horrible... is there a "NSStringFromSelector" type of thing ?

@malhal 2014-06-06 15:11:07

can't believe they designed for unchecked selectors since objc had this

@rickster 2014-08-08 22:15:31

@malcomhall: @selector is handy, but it's not enforced as formally as you might think. "Undeclared selector" is merely a warning from the compiler, because new selectors can always be introduced at run time. Verifiable/refactorable selector references in Swift would be a good feature request to make, though.

@cynistersix 2014-11-12 22:55:47

This answer is helpful but the answer below with @objc is more appropriate.

@levous 2015-08-04 11:53:54

When you are passing the selector string in as a variable or parameter, you'll need to let the compiler know its a selector using the Selector() function. thanks

@zoul 2016-02-23 10:17:21

Since Selector conforms to StringLiteralConvertible, you can just use a plain string instead of the Selector(…) construct.

Related Questions

Sponsored Content

17 Answered Questions

[SOLVED] How do I call Objective-C code from Swift?

  • 2014-06-02 20:05:42
  • David Mulder
  • 269855 View
  • 927 Score
  • 17 Answer
  • Tags:   objective-c swift

15 Answered Questions

[SOLVED] Check for internet connection with Swift

19 Answered Questions

[SOLVED] #pragma mark in Swift?

  • 2014-06-03 14:05:56
  • Arbitur
  • 210681 View
  • 901 Score
  • 19 Answer
  • Tags:   swift

6 Answered Questions

[SOLVED] Passing an array to a function with variable number of args in Swift

31 Answered Questions

[SOLVED] How would I create a UIAlertView in Swift?

5 Answered Questions

[SOLVED] How can I deal with @objc inference deprecation with #selector() in Swift 4?

  • 2017-06-06 12:44:48
  • LinusGeffarth
  • 41162 View
  • 128 Score
  • 5 Answer
  • Tags:   swift xcode swift4

2 Answered Questions

[SOLVED] NSTimer Swift difficulty

  • 2015-04-22 00:16:45
  • Chris Hunter
  • 451 View
  • 1 Score
  • 2 Answer
  • Tags:   swift nstimer

6 Answered Questions

[SOLVED] Does Swift init(count:, repeatedValue:) work?

3 Answered Questions

[SOLVED] What is a slice in Swift?

  • 2014-06-06 02:33:30
  • hjing
  • 36853 View
  • 85 Score
  • 3 Answer
  • Tags:   swift slice

3 Answered Questions

[SOLVED] Could not find an overload for “init” that accepts the supplied arguments SWIFT

  • 2014-10-22 16:02:03
  • patrikbelis
  • 2422 View
  • 6 Score
  • 3 Answer
  • Tags:   ios xcode swift

Sponsored Content