Swift: Using Selectors with Multiple Arguments

我与影子孤独终老i 提交于 2021-02-11 07:12:44

问题


I'm trying to keep an NSTimer in the model of my application and update the time in my view controller file. To do this I created these two methods:

func startTimer(labelToUpdate : UILabel) {
    timerGoing = true
    timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "decTimeByOne:labelToUpdate:", userInfo: labelToUpdate, repeats: true)
}

func decTimeByOne(labelToUpdate : UILabel) {
        if timerGoing {
            if decreasingTime > 0 {
                decreasingTime--;
                labelToUpdate.text = "\(decreasingTime)"
            }
            else {
                timerGoing = false
                timer.invalidate()
            }
        }
    }

I get runtime exception (I believe) in the console that there is an "Unrecognized selector". After doing some research, I was under the impression that this was the syntax used in Swift to call multiple argument methods within selectors: selector: "methodName:argumentName:", userInfo: argumentPassedIn,

In the end, I would like to keep a timer associated with my model's object and merely have that time updated and displayed in my apps view. Is this the correct way of going about this?


回答1:


I was under the impression that this was the syntax used in Swift to call multiple argument methods within selectors: `selector: "methodName:argumentName:"

In a way that's true, but it doesn't relieve you of the responsibility, if you're going to use an NSTimer, of reading the docs on NSTimer. In particular, it doesn't change the fact that the selector called by an NSTimer is not up to you. It can only be of the form methodName:, because it takes just one parameter — the timer (not a label or anything else). As you've already been told, if you have other information to pass, attach it to the timer, which is what will be passed.

Now, in addition, you are also wrong about how to state the name of your method. The selector for a method declared as func decTimeByOne(labelToUpdate : UILabel is decTimeByOne:. Again, that is not up to you; you have to know the rules for how to make a selector.




回答2:


Store everything in an array and pass that to userInfo. Then you can pass whatever you'd like.

func startTimer(labelToUpdate : UILabel) {
    var array = [labelToUpdate, otherStuff]

    timerGoing = true
    timer = NSTimer.scheduledTimerWithTimeInterval(1, target: self, selector: "decTimeByOne:", userInfo: array, repeats: true)
}

func decTimeByOne(labelToUpdate : UILabel) {
     var array = labelToUpdate.userInfo
        if timerGoing {
            if decreasingTime > 0 {
                decreasingTime--;
                labelToUpdate.text = "\(decreasingTime)"
            }
            else {
                timerGoing = false
                timer.invalidate()
            }
        }
    }


来源:https://stackoverflow.com/questions/29756914/swift-using-selectors-with-multiple-arguments

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!