internal convenience init of super class extension not accessible after update to swift 3.1, SDK 10.3 and XCode 8.3

Hello.

We have extension like this

internal extension UIGestureRecognizer {

internal convenience init<T: UIGestureRecognizer>(handler: @escaping (T) -> Void, type: T.Type) {

let handler = ClosureHandler<T>(handler: handler)

self.init(target: handler, action: ClosureHandlerSelector)

handler.control = (self as! T)

setHandler(handler)

}


then, we are going to use it from



public extension UITapGestureRecognizer {

public convenience init(taps: Int = 1, touches: Int = 1, handler: @escaping (UITapGestureRecognizer) -> Void) {

self.init(handler: handler, type: UITapGestureRecognizer.self)

numberOfTapsRequired = taps

numberOfTouchesRequired = touches

}

}

but convenience init<T: UIGestureRecognizer>(handler: @escaping (T) -> Void, type: T.Type) is unaccessable with error Argument labels '(handler:, type:)' do not match any available overloads

Before last update all works.

It shouldn't work in the above example.


You've defined a convenience init for class UITapGestureRecognizer, and convenience inits are required to call "across" (that is, to call another initializer in UITapGestureRecognizer), and may not call "up" (that is, call an initializer in the superclass UIGestureRecognizer).


It sounds like the compiler was previously allowing UITapGestureRecognizer to inherit the UITapGestureRecognizer convenience init, in which case your call would have been "across" and not "up", or some other quirk of syntax, access or generics that allowed the call to succeed.


If you try changing the first init to a designatied initializer, does the error message go away?

Sorry.

designatied initializer in extension?

As templolary solution I'm calling designated init of super class from UITapGestureRecognizer convinient init in extention like that

public convenience init(taps: Int = 1, touches: Int = 1, handler: @escaping (UITapGestureRecognizer) -> Void) {

let handler = ClosureHandler<UITapGestureRecognizer>(handler: handler)

self.init(target: handler, action: ClosureHandlerSelector)

handler.control = (self)

setHandler(handler)

numberOfTapsRequired = taps

numberOfTouchesRequired = touches

}

But I cant upderstant why before update it works.

Kindly point me in change log of this feature.

Yes, well, I forgot about that restriction.


Under the circumstances (of weaving your own convenience code around a Cocoa Touch class, where you not in total control), you have to be pragmatic. You could simply add the couple of lines of code from the UIGestureRecognizer init to each subclass init. Or package those lines as a func that subclasses can call from their inits. Or subclass these classes instead of extending them.


Or, just get rid of the subclass init. I'm not sure what the conceptual load is, for clients of UITapGestureRecognizer that need a number of taps other than 1 or number of touches other than 1, in assigning to the new object's standard properties vs. optionally passing the same values into the init.

>> why before update it works


It was a bug that's been fixed. Isn't it enough to know that your old code broke the documented rules?


I'm not in a position to find the specific change log that fixed the problem (perhaps as a side effect of something else). If you need to know, go over to the swift.org forums and ask there. Someone there will know more about it.

I'm not agree about rules i.e.

Rule 1

If your subclass doesn’t define any designated initializers, it automatically inherits all of its superclass designated initializers.

Rule 2

If your subclass provides an implementation of all of its superclass designated initializers—either by inheriting them as per rule 1, or by providing a custom implementation as part of its definition—then it automatically inherits all of the superclass convenience initializers.”


Thank you for your time.

Yes, you're right. Submit a bug report, and/or check on the forums over at swift.org to see if anyone has a workaround.

internal convenience init of super class extension not accessible after update to swift 3.1, SDK 10.3 and XCode 8.3
 
 
Q