Open carlos-chaguendo opened 6 years ago
I don't think it works for some classes that take parameters.
That's true, but for classes that don't need parameters it's very useful, keeping in mind that many times we can omit those parameters and set them in the code block
let label = UILabel(frame: CGRect(x: 0, y: 0, width: 100, height: 20)).then {
$0.textAlignment = .center
$0.textColor = .black
$0.text = "Hello, World!"
}
equals to
let label = UILabel {
$0.frame = CGRect(x: 0, y: 0, width: 100, height: 20)
$0.textAlignment = .center
$0.textColor = .black
$0.text = "Hello, World!"
}
I think the second option is easier to understand.
I'm worried about adding a custom initializer to existing types. I found there is a crash when using a custom NSObject subclass that doesn't implement init()
.
import Foundation
protocol Then {}
extension NSObject: Then {}
extension Then where Self: NSObject {
init(block: (Self) -> Void) {
self.init()
block(self)
}
}
class Foo: NSObject {
var name: String?
init(handler: () -> Void) {
super.init()
}
}
// Fatal error: Use of unimplemented initializer 'init()' for class '__lldb_expr_2.Foo'
let foo = Foo {
$0.name = ""
}
The compiler cannot ensure that we're not using the safe initializer. Do you have an idea?
https://docs.swift.org/swift-book/LanguageGuide/Initialization.html
Subclasses do not inherit their superclass initializers by default. However, superclass initializers are automatically inherited if certain conditions are met.
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.
These rules apply even if your subclass adds further convenience initializers.
your error is caused by creating an initializer
class Foo: NSObject {
init(handler: () -> Void) {
super.init()
}
}
// the initializer `init()` was not inherited *Rule1*
Foo.init()
That said, it can be assumed that the correct implementation is:
class Foo: NSObject {
var name: String?
override init() {
super.init()
}
init(handler: () -> Void) {
super.init()
}
}
In my opinion, this type of case should be specified in the documentation of Then
@devxoul What do you think of this syntax?