4

What is the difference between:

#selector(Aclass.someMethod) and #selector(self.someMethod)

someMethod is an instance function and I'm calling inside AClass like this:

NSNotificationCenter.defaultCenter().addObserver(self, 
  selector: #selector(self.someMethod), // #selector(Aclass.method)
  name: "REMoveOrderViewRefresh", 
  object: nil
)
JAL
  • 41,701
  • 23
  • 172
  • 300
aguilarpgc
  • 1,181
  • 12
  • 24
  • The [proposal for `#selector`](https://github.com/apple/swift-evolution/blob/master/proposals/0022-objc-selectors.md) never mentions the `self.method` syntax, so I'm wondering if it only accidentally works. – zneak Apr 07 '16 at 20:38
  • 1
    @dfri nice find, didn't know about that! (out of votes, will come back at 12 midnight UTC if this hasn't been closed yet) – JAL Apr 07 '16 at 20:54

1 Answers1

4

If you're referencing a selector from your own class, there should be no difference, since self points to Aclass.

If you are referencing a selector from another class, you must explicitly call Aclass.someMethod, since the selector is not on self but on a different object.

class MyClass: NSObject {
    func someFunc() {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: #selector(self.someOtherFunc(_:)), name: "someEvent", object: nil)
    }

    func someOtherFunc(notification: AnyObject) {
        //
    }
}

class OtherClass: NSObject {

    func anotherFunc() {
        let myInstance = MyClass()

        NSNotificationCenter.defaultCenter().addObserver(myInstance, selector: #selector(MyClass.someOtherFunc(_:)), name: "someEvent", object: nil)
    }
}
JAL
  • 41,701
  • 23
  • 172
  • 300
  • I could very well be wrong here, but calling self on a class returns the class name, but calling self on an instantiated object returns that particular instance doesn't it? So based on that self.someMethod wouldn't work? – Scriptable Apr 07 '16 at 20:24
  • @Scriptable unless I'm mistaken `#selector(MyClass.someOtherFunc(_:))` points to that specific method on an instance of a class. The selector just needs to be explicitly defined as a method on a class. I'll gladly step back and let the pros answer if this is wrong. – JAL Apr 07 '16 at 20:26
  • that was just my understanding.. hoping a pro would point me in the right direction haha. I'm quite curious now, I'll have to try it – Scriptable Apr 07 '16 at 20:27
  • This answer is my understanding of the new `#selector` constructor. – JAL Apr 07 '16 at 20:27
  • compiler doesn't complain about it, good enough for me. cheers. Learnt something there. prevented me giving a false answer :) – Scriptable Apr 07 '16 at 20:30
  • MyClass.someFunc() can not point to a method on an instance of a class because there is no creation of an instance involved in this expression. It just points to the declaration of that method of that class. Even if MyClass.someFunc() would be a (static) class-method there would be no creation of an instance involved. That's the reason why you can not refer to "self" in a class-method. – Darko Apr 07 '16 at 20:45
  • 1
    @Darko: The Swift `#selector` syntax is a bit special (and peculiar), as compared to the general rules of class vs instance methods. The compiler will resolve `#selector(Aclass.someMethod)` for _instance method_ `someMethod` to an instance of `Aclass`. See [matt:s Q&A for details](http://stackoverflow.com/questions/35658334/how-do-i-resolve-ambiguous-use-of-compile-error-with-swift-selector-syntax). – dfrib Apr 07 '16 at 20:58
  • @dfri The compiler cannot resolve `#selector(Aclass.someMethod)` to an instance of a class, that's why the `target` parameter is needed. To find the "way" to the instance. That's the usual `self` at `addObserver(self... `. – Darko Apr 07 '16 at 21:07
  • Apart from this: instantiation is nothing else as the allocation of memory for a particular type. This happens during runtime, not compile time. The #selector syntax basically just checks if that particular given method is a valid ObjC method. Passing a pure Swift function does not work here. – Darko Apr 07 '16 at 21:19
  • I didn't see the other post but your comments are very helpful, hmm, should I delete this post? – aguilarpgc Apr 07 '16 at 21:46
  • @aguilarpgc Duplicate questions can be kept as signposts. If you think the discussion in the comments will be helpful to others, keep the post. You can also accept my answer if you feel that it has helped you. – JAL Apr 07 '16 at 21:51
  • 1
    @Darko: You're right, the target is naturally needed to resolve the instance. You can, however, if you are _within_ `Aclass`, and want to add a selector to a method (objc) _in_ `Aclass`, use `#selector(self.someMethod)` just as well as `#selector(Aclass.someMethod)`. – dfrib Apr 07 '16 at 21:58
  • Yes, of course you can. Both expressions point to the same. I mean - just try it. It clearly works. :) But that was not what I wanted to say. I just wanted to clarify that self.someMethod does nowhere point to an instance of self. Just self points to self. Maybe I'm a little bit over-picky. Sorry for that. :) – Darko Apr 07 '16 at 23:28