17

Sorry for these questions

I have 4 questions about Selector in swift.

FIRST Question

I am wondering what is the proper way to use selector in swift

closeBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Stop, target: self, action: Selector("closeBarButtonItemClicked:"));

VS

closeBarButtonItem = UIBarButtonItem(barButtonSystemItem: UIBarButtonSystemItem.Stop, target: self, action: "closeBarButtonItemClicked:");

Should we use Selector("methodName:") or "methodName:" right away?

Both way works but which one is the correct way?

SECOND Question

How do we call a function with a parameter in Swift? Let's say I want to call a function like this

func methodName(parameterOne : String, parameterTwo: String)

THIRD Question

How do we call a type method using Selector in swift? is it even possible at all?

class SomeClass {
class func someTypeMethod() {
// type method implementation goes here
  }
}

FOURTH Question

What is the purpose of that colon behind the function name in Selector?

Eric Aya
  • 69,473
  • 35
  • 181
  • 253
JayVDiyk
  • 4,277
  • 22
  • 70
  • 135
  • 7
    As to your last question, there is no colon after the function name. The colon is *a part of* the function name. The function named `xyz:` is an entirely different function from the one named `xyz`. – Hot Licks Jan 28 '15 at 03:57
  • 1
    http://stackoverflow.com/questions/24007650/selector-in-swift this post has a detailed explanation on selectors – Gerald Apr 09 '16 at 03:08
  • Don't beg for rep or upvotes. Thanks. – Eric Aya Apr 22 '16 at 11:26
  • 1
    Thanks @EricD Please help me remove the rest of the ones I did. Didn't know it is not allowed. – JayVDiyk Apr 22 '16 at 11:27
  • Don't worry, I've reverted these edits. Just avoid doing this sort of thing in the future. :) Thanks. – Eric Aya Apr 22 '16 at 11:30

3 Answers3

17

@ad121's answer is great—just want to add a little context to #1:

The Selector type has been extended in Swift to be StringLiteralConvertible. Any time a Selector instance is expected, you can give a string literal instead and a Selector instance will be created for you. This means you can also create a Selector instance from a string literal manually:

let mySelector: Selector = "methodName:withParameter:"

Note that this doesn't mean a String can be used interchangeably with a Selector—this only works with string literals. The following will fail:

let methodName = "methodName:withParameter:"
let mySelector: Selector = methodName
// error: 'String' is not convertible to 'Selector'

In that case you'd need to actually call the Selector constructor yourself:

let methodName = "methodName:withParameter:"
let mySelector = Selector(methodName)
Nate Cook
  • 92,417
  • 32
  • 217
  • 178
14

Question 1: I don't think there is really a correct way. I personally prefer the second way, but both work so I don't think it really matters.

Question 2: I just reread you question. I think you mean how to call that in a selector. The selector for that I believe would be "methodName:parameterTwo:" but I am not positive, as the selector with two parameters probably should have an external parameter name to place in the selector where parameterTwo is in my answer.

Old question 2 answer (prior to edit): You would call that function as methodName(variable1, parameterTwo: variable2). If you wanted to make them say the parameter name in the call you could make the header methodName(calledVarName parameterOne: String, calledVarName2 parameterTwo: String). This would be called as methodName(calledVarName: variable1, calledVarName2: variable2). You could also define the header as methodName(#parameterOne: String, #parameterTwo: String). This would be called as methodName(parameterOne: variable1, parameterTwo: variable2). Read more here: https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Functions.html

Question 3: I can't say for sure, but I dont think there is a way to make a selector for this. If there is I assume it would be "someTypeMethod"

Old question 3 answer (prior to edit): You can call this method by SomeClass.someTypeMethod().

Question 4: The colon signifies that the function header has a parameter. So "function1:" corresponds to func function1(someParameterName: AnyObjectHere) while "function1" corresponds to func function1().

ad121
  • 2,268
  • 1
  • 18
  • 24
4

Answering your 3rd question: You can totally do this. Just set the target parameter to the type itself.

Say you have a class defined:

class SomeType {
    class func someMethod() {}
    func someMethod() {}
}

Now taking your example, this will call the instance method:

let something = SomeType()
let closeBarButtonItem = UIBarButtonItem(barButtonSystemItem:UIBarButtonSystemItem.Stop, target: something, action: "someMethod")

Change the target and the call will get forwarded to the type:

let closeBarButtonItem = UIBarButtonItem(barButtonSystemItem:UIBarButtonSystemItem.Stop, target: SomeType.self, action: "someMethod")
Dmitry
  • 376
  • 3
  • 15