Non-designated initialiser inheritance from Objective C classes problem where initialiser calls another initialiser on self

Originator:rupert
Number:rdar://21648907 Date Originated:02-Jul-2015 09:39 AM
Status:Open Resolved:
Product:Developer Tools Product Version:Xcode 6.4 (6E35b)
Classification: Reproducible:Always
 
Summary:
Objective C classes allow subclasses to automatically inherit superclass initialisers, even if they do not implement them, which means that an Objective C class initialiser can call an initialiser on self, even though the actual implementation is in the superclass.
In Swift this does not seem to be the case, leading to incompatibilities between Objective C classes and their Swift subclasses where calling the Objective C superclass initialiser from a custom Swift initialiser results in the Objective C initialiser attempting to call an initialiser on self which is no longer available in the Swift subclass.

Steps to Reproduce:
* Create a vanilla project (I use iOS but the problem should be exactly the same for OSX) using both Objective C and Swift;
* create an Objective C sub-class of an existing class with multiple designated initialisers (for example UIView);
* implement a custom initialiser on this subclass, which calls a parent-inherited initialiser through self (for example custom initWithIdentifier: calls [self initWithFrame:CGRectZero]);
* create a Swift subclass of the Objective C class that you created;
* implement a custom initialiser on the Swift class that you created which calls the custom initialiser that you created in its Objective C superclass (for example custom Swift initialiser init(name:) calls super.init(identifier:));
* attempt to instantiate your custom Swift subclass anywhere in your project.

Expected Results:
Successful creation of an instance of the Swift subclass.

Actual Results:
A fatal error is thrown concerning the "use of unimplemented initializer" [name of initialiser that the Objective C subclass calls with self] "for class" [name of Swift subclass]

Version:
Version 6.4 (6E35b), OSX 10.10.4 (14E46)

Notes:
This is concerning because it basically makes it impossible to subclass UIKit classes such as UITableViewController and MKAnnotationView by adding immutable properties which need to be injected on instantiation.

Configuration:
Always occurs in iOS simulator iOS 8.4 on MacBook Pro (Retina, 13-inch, Late 2013)
Always occurs on iPhone 4S on iOS 8.4

Comments

I think this is not supposed to be a bug as per the design of designated initializers?

If you look at "Initializer Delegation for Class Types" in https://developer.apple.com/library/mac/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-ID203 you'll see that a convenience initializer (which you call "custom initializer" on this text) has to ultimately call a designated initializer in the same class.

So I think your init(name:) (convenience initializer) may not call super.init(identifier:) (convenience initializer in the super class). If you made both designated initializers (which means they must call a designated initializer of the super class) this won't happen. Or if you make init(name:) call a designated initializer in the Swift subclass that shouldn't happen either.

I hope this solves your problem. If it does consider closing this rdar


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!