How many times have you wanted mutate self in the initializer? Apparently it’s totally possible in swift, just not an enabled feature. It’s on Apples radar and Chris Lattner has acknowledged it:
@thanegill It would have to have the same type as the dynamic Self type, to work w/ derived classes. Enabling this hasn’t been a priority.
— Chris Lattner (@clattner_llvm) October 22, 2015
Submitting this as a proposal on the Swift evolution mailing list still yet to be done. Let me know if you’d like to help write up a proposal.
As Salva Pestov pointed out to me protocol extensions can mutate self as they are never inherited. This this is now possible, though a bit ugly:
public protocol MutateSelf { }
extension MutateSelf {
public init(mutateSelfAs object: Self) {
self = object
}
// Failable initializer, useful for objects that conform to RawRepresetable
public init?(mutateSelfAs object: Self?) {
if let object = object {
self = object
} else {
return nil
}
}
}
This leads to cool uses that make UIKit more swifty:
// Extending NSObject becasue AnyObject cannot be extended
extension NSObject: MutateSelf { }
extension UIViewController {
convenience init(fromStoryboard storyboard: UIStoryboard, storyboardID id: String) {
self.init(mutateSelfAs: storyboard.instantiateViewControllerWithIdentifier(id))
}
}
class SomeViewController: UIViewController {
let object: SomeObject
convenience init(fromStoryboard storyboard: UIStoryboard, object: SomeObject) {
self.init(fromStoryboard: storyboard)
self.object = object
}
func methodThatShowsAView() {
let newViewController = NewViewController(fromStoryboard: self.storyboard!, object: self.object)
self.navigationController?.pushViewController(newViewController, animated: true)
}
}
This also fixes my displease with dependency injection and removes the need for forced unwrapped optionals! 🎉 You can now just initialize your new VC passing it the current storyboard and push to it with your navigation controller. Much simpler and easier to read!