[swift-users] Calling default implementation of protocol methods as selectors

Geordie Jay geojay at gmail.com
Sun Jun 4 00:06:15 CDT 2017


That's why I thanked for for the amendment. As I said, typing code blindly
on the phone, mistakes are inevitable. Thanks for clearing it up.
On Sun 4. Jun 2017 at 15:04, Zhao Xin <owenzx at gmail.com> wrote:

> I was not talking about the formatting. I am talking about the
> implementation.
>
> You can't use `self` before you call `super.init` as you did now. If
>  changing your implementation to called `super.init` and then call `self`
> in `super.init` again. You would have called `super.init` twice. I don't
> know what that means. But it smells bad.
>
> Zhaoxin
>
> On Sun, Jun 4, 2017 at 12:51 PM, Geordie Jay <geojay at gmail.com> wrote:
>
>> Thanks for the amendment, and sorry for the (lack of) formatting. I
>> painstakingly typed that on my phone with manually-spaced indenting, which
>> the Inbox app unhelpfully removed entirely when I pressed send. Pasting
>> into Xcode should do the trick though..
>>
>> Geordie
>>
>> On Sun 4. Jun 2017 at 14:49, Zhao Xin <owenzx at gmail.com> wrote:
>>
>>> You should change to another way. Using `self` in `super.init` is not
>>> allowed.
>>>
>>> Zhaoxin
>>>
>>> On Sun, Jun 4, 2017 at 12:38 PM, Geordie Jay <geojay at gmail.com> wrote:
>>>
>>>> I am dealing with a variant of this on Android right now. I have just
>>>> subclassed e.g. UITapGestureRecognizer to perform the 2nd variant above and
>>>> externally accept a closure as its argument. I'm writing this on my phone
>>>> so forgive any syntax errors or accidental omissions:
>>>>
>>>> class TapGestureRecognizer: UITapGestureRecognizer {
>>>> var onTap: (() -> Void)?
>>>> init(onTap: (() -> Void)?) {
>>>> self.onTap = onTap
>>>> super.init(target: self, action: #selector(internalTapHandler))
>>>> }
>>>>
>>>> @objc private func internalTapHandler() {
>>>> onTap?()
>>>> }
>>>> }
>>>>
>>>> class Baz: Foo {
>>>> init() {
>>>> let tapRecognizer = TapGestureRecognizer(onTap: self.bar)
>>>> }
>>>> }
>>>>
>>>>
>>>> Cheers,
>>>> Geordie
>>>>
>>>> On Sat 3. Jun 2017 at 16:53, Nate Birkholz via swift-users <
>>>> swift-users at swift.org> wrote:
>>>>
>>>>> Thanks, the second had occurred to me, but felt a little too much like
>>>>> in practice it would make the code harder to understand.
>>>>>
>>>>> On Fri, Jun 2, 2017 at 9:58 PM, Zhao Xin <owenzx at gmail.com> wrote:
>>>>>
>>>>>> I found two workarounds.
>>>>>>
>>>>>> 1.
>>>>>>
>>>>>> protocol Foo: class {
>>>>>>
>>>>>>     func bar()
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>> class Base:Foo {
>>>>>>
>>>>>>     @objc func bar() {
>>>>>>
>>>>>>         print("bar")
>>>>>>
>>>>>>     }
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>> class Baz: Base {
>>>>>>
>>>>>>     override init() {
>>>>>>
>>>>>>         super.init()
>>>>>>
>>>>>>         let tapRecognizer = UITapGestureRecognizer(target: self,
>>>>>> action: #selector(bar))
>>>>>>
>>>>>>     }
>>>>>>
>>>>>> }
>>>>>>
>>>>>> 2.
>>>>>>
>>>>>> protocol Foo: class {
>>>>>>
>>>>>>     func bar()
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>> extension Foo {
>>>>>>
>>>>>>     func bar() {
>>>>>>
>>>>>>         print("bar")
>>>>>>
>>>>>>     }
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>> class Baz: Foo {
>>>>>>
>>>>>>     init() {
>>>>>>
>>>>>>         let tapRecognizer = UITapGestureRecognizer(target: self,
>>>>>> action: #selector(delegate))
>>>>>>
>>>>>>     }
>>>>>>
>>>>>>
>>>>>>
>>>>>>     @objc func delegate() {
>>>>>>
>>>>>>         bar()
>>>>>>
>>>>>>     }
>>>>>>
>>>>>> }
>>>>>>
>>>>>>
>>>>>> Zhao Xin
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> On Sat, Jun 3, 2017 at 10:35 AM, Nate Birkholz via swift-users <
>>>>>> swift-users at swift.org> wrote:
>>>>>>
>>>>>>> protocol Foo: class {
>>>>>>>     func bar()
>>>>>>> }
>>>>>>>
>>>>>>> extension Foo {
>>>>>>>     func bar() {
>>>>>>>          print("bar")
>>>>>>>     }
>>>>>>> }
>>>>>>>
>>>>>>> class Baz: Foo {
>>>>>>>     init() {
>>>>>>>         let tapRecognizer = UITapGestureRecognizer(target: self,
>>>>>>> action: #selector(bar))
>>>>>>>     }
>>>>>>> }
>>>>>>>
>>>>>>> the #selector tells me: "Argument of '#selector' refers to instance
>>>>>>> method 'bar()' that is not exposed to Objective-C" and asks me to add @objc
>>>>>>> to the method definition.
>>>>>>>
>>>>>>> Adding @objc to the method tells me: "@objc can only be used with
>>>>>>> members of classes, @objc protocols, and concrete extensions of classes"
>>>>>>>
>>>>>>> Adding @objc to the protocol doesn't fix it, just introduces new
>>>>>>> issues.
>>>>>>>
>>>>>>> "dynamic" cannot be applied to a protocol, so cannot be used
>>>>>>> alternatively.
>>>>>>>
>>>>>>> Is there a way to get around this? If a method is called by a
>>>>>>> gesture recognizer, is there no way to have a default protocol
>>>>>>> implementation? I'd like to use default implementations if possible to make
>>>>>>> my code more DRY.
>>>>>>>
>>>>>>> Is there a roadmap/plan for swift-native selector dispatch?
>>>>>>>
>>>>>>> Thanks. I look forward to the inevitable reply revealing the dumb
>>>>>>> thing I missed. :)
>>>>>>>
>>>>>>> --
>>>>>>> Nate Birkholz
>>>>>>>
>>>>>>> _______________________________________________
>>>>>>> swift-users mailing list
>>>>>>> swift-users at swift.org
>>>>>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>>>>>
>>>>>>>
>>>>>>
>>>>>
>>>>>
>>>>> --
>>>>> Nate Birkholz
>>>>> _______________________________________________
>>>>> swift-users mailing list
>>>>> swift-users at swift.org
>>>>> https://lists.swift.org/mailman/listinfo/swift-users
>>>>>
>>>>
>>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-users/attachments/20170604/f26e9b15/attachment.html>


More information about the swift-users mailing list