NSTimer with Parameter

Hi all.


Below code works fine, (strText is a defined outside)


    func typeLetter1(){
        var arrText = Array( strText.characters)
        if intCounter < arrText.count {
            let randomInterval = Double((arc4random_uniform(8)+2))/100
            tmrTimer?.invalidate()
            tmrTimer = NSTimer.scheduledTimerWithTimeInterval(randomInterval, target: self,
selector: #selector(ViewController.typeLetter1), userInfo: nil, repeats: false)
            lblFirst.text = lblFirst.text! + String(arrText[intCounter])
        } else {
            tmrTimer?.invalidate()
        }
        intCounter += 1
    }


However when I try to modify it by moving strText to function parameters it does not. What is the correct way to re-write below code ?


    func typeLetter1(strText:String){
        var arrText = Array( strText.characters)
        if intCounter < arrText.count {
            let randomInterval = Double((arc4random_uniform(8)+2))/100
            tmrTimer?.invalidate()
            tmrTimer = NSTimer.scheduledTimerWithTimeInterval(randomInterval, target: self,
selector: #selector(ViewController.typeLetter1(strText)), userInfo: nil, repeats: false)
            lblFirst.text = lblFirst.text! + String(arrText[intCounter])
        } else {
            tmrTimer?.invalidate()
        }
        intCounter += 1
    }


XCode already promps this code is wrong "selector: #selector(ViewController.typeLetter1(strText))" but I could not figure out how to code it correctly.


Thanks in advance...

Accepted Reply

In fact, you cannot.


The func in selector pass the timer itself as argument, not your own argument !


Have a look at these 2 articles (sorry, they are old for Swift2, but bthe rationale remains)


http : / / stackoverflow.com/questions/26659735/xcode-swift-how-to-use-a-function-that-takes-a-parameter-as-a-selector


http : / / stackoverflow.com/questions/24889279/passing-parameters-to-a-method-called-by-nstimer-in-swift


PS: why do you want to call the function recusrsively at the end of the timer ?

Replies

You should probably write without explicit name of parameter (which must be of type anyObject)


#selector(ViewController.typeLetter1(_:))

Dear Claude;


Thanks once more with the reply. It worked just fine for the error prompt Xcode has given at the first stage (it has dissapeared) however now when I run the code I get "thread 1 -signal sigabrt" error.


When I run the code without explicit name of the parameter at the timer, how does Xcode figure out which parameter it will use when I call the function like;

typeLetter1("abcd")

on the second run (after the timer fires)


Maybe it is the reason of the error or I am doing something wrong.

In fact, you cannot.


The func in selector pass the timer itself as argument, not your own argument !


Have a look at these 2 articles (sorry, they are old for Swift2, but bthe rationale remains)


http : / / stackoverflow.com/questions/26659735/xcode-swift-how-to-use-a-function-that-takes-a-parameter-as-a-selector


http : / / stackoverflow.com/questions/24889279/passing-parameters-to-a-method-called-by-nstimer-in-swift


PS: why do you want to call the function recusrsively at the end of the timer ?

Dear Claude;


I got it, thanks for your answer and your time.


Original code was not mine, it was shared on the net and I just tried to modify it for my needs.

Now I decided to rewrite it from scratch which I think will be the best approach.

Yes, it is always better to rewrite and not just copy. It's the best way to learn how it all works (another way is to try to explain to others, like answering questions in this forum, which is why I do appreciate it).


wish you good.

Note sure if you know this already, but the most recent OS releases support a block-based timer API, which allows you to capture values naturally.

let strText = "Hello Cruel World!"
Timer.scheduledTimer(withTimeInterval: 1.0, repeats: false) { timer in
    print(strText)
}

Share and Enjoy

Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware

let myEmail = "eskimo" + "1" + "@apple.com"