Is this a typo in the example, pref
is never used?! Otherwise I don't understand the purpose of this example except that it shows an unambiguous init(pref:)
as a factory init.
Other than that, Swift still does not allow the usage of Self
in classes (SE-0068 is still not implemented after years). In the given example I read Self
as it would mean the same thing like if you had a protocol with Self
that this class conforms to. I had a short discussion on twitter [1] with @Slava_Pestov about the proposal a while ago. I must admit that I did not fully understand the technical issue with Self
, but he said that we have to reconsider what Self
would mean on classes. It seems that the reconsideration of Self
touches this pitch since we need to clarify what the following code means:
extension Y {
convenience init(other: Self) {
self = other
}
}
Or what does Self
means in the related thread from the [1] discussion in case of a generic type parameter:
Nevertheless I really like the general sense of this pitch especially if combined with SE-0068. Then I can finally refactor this pattern to something more naturally hidden:
// Before
protocol XibDesignable : AnyObject {}
extension XibDesignable where Self : UIView {
static func instantiateFromXib() -> Self {
let metatype = Self.self
let bundle = Bundle(for: metatype)
let nib = UINib(nibName: "\(metatype)", bundle: bundle)
guard let view = nib.instantiate(withOwner: nil, options: nil).first as? Self else {
fatalError("Could not load view from nib file.")
}
return view
}
}
// After:
extension UIView {
static func instantiateFromXib() -> Self {
let metatype = Self.self
let bundle = Bundle(for: metatype)
let nib = UINib(nibName: "\(metatype)", bundle: bundle)
guard let view = nib.instantiate(withOwner: nil, options: nil).first as? Self else {
fatalError("Could not load view from nib file.")
}
return view
}
}
final class View : UIView {
convenience init() {
self = Self.instantiateFromXib()
}
}