swift subclasses used in generics don't get called when inheriting from NSObject

前端 未结 3 1941
面向向阳花
面向向阳花 2021-01-14 20:44

Partial Solution Update at the end!

Attached is code that produces odd behavior. I copied it out of a swift playground so it should run in one fine.

3条回答
  •  渐次进展
    2021-01-14 21:07

    I was able to confirm your results and submitted it as a bug, https://bugs.swift.org/browse/SR-10617. Turns out this is a known issue! I was informed (by good old Hamish) that I was duplicating https://bugs.swift.org/browse/SR-10285.

    In my bug submission, I created a clean compact reduction of your example, suitable for sending to Apple:

    protocol P {
        init()
        func doThing()
    }
    
    class Wrapper {
        func go() {
            T().doThing()
        }
    }
    
    class A : NSObject, P {
        required override init() {}
        func doThing() {
            print("A")
        }
    }
    
    class B : A {
        required override init() {}
        override func doThing() {
            print("B")
        }
    }
    
    Wrapper().go()
    

    On Xcode 9.2, we get "B". On Xcode 10.2, we get "A". That alone is enough to warrant a bug report.

    In my report I listed three ways to work around the issue, all of which confirm that this is a bug (because none of them should make any difference):

    • make the generic parameterized type's constraint be A instead of P

    • or, mark the protocol P as @objc

    • or, don't have A inherit from NSObject


    UPDATE: And it turns out (from Apple's own release notes) there's yet another way:

    • mark A's init as @nonobjc

提交回复
热议问题