[swift-evolution] [Pitch] Setup Block

Derrick Ho wh1pch81n at gmail.com
Sat Nov 19 17:41:48 CST 2016


You could try awakeFromNib which is called when interface builder creates
the view.

But if you are instantiating it programmatically, the closest thing would
be drawRect. It calls multiple times so you may need to add logic to ensure
that it only happens once.


I think a "didFinishInitialing" method would be a decent addition to the
uikit framework but it doesn't reduce much boilerplate code.
On Sat, Nov 19, 2016 at 6:28 PM Andrew Arnopoulos via swift-evolution <
swift-evolution at swift.org> wrote:

> Hello Swift Community,
>
> To start, I am new to the mail list so please forgive me for any faux pas
> I may have committed. In addition, please excuse me if this feature has
> already been proposed.
>
> I have noticed, especially with UIKit classes, that I am consistently
> overriding initializers in order to call a setup function. In order to keep
> the class consistent I have to write a bunch of boilerplate code and this
> becomes more of a problem when the number of initializers increase. The
> code below is a simple example of some of the boilerplate needed to write a
> subclass of UIButton.
>
> class MyButton: UIButton {
>     override init(frame: CGRect) {
>         super.init(frame: frame)
>         setup()
>     }
>
>     convenience init() {
>         self.init(frame: CGRect.zero)
>     }
>
>
>     required init?(coder aDecoder: NSCoder) {
>         super.init(coder: aDecoder)
>         setup()
>     }
>
>
>     private func setup() {
>         // Setup for custom class
>     }
> }
>
> What I am proposing is a setup block that is called after every
> non-convience initializer. The code might look something like the code this:
>
> class MyButton: UIButton {
>
>     convenience init() {
>         self.init(frame: CGRect.zero)
>     }
>
>     setup {
>         // Setup for custom class
>     }
> }
>
> Every subclass would have a setup block that would be called after ever
> initializer returns, that includes subsequent calls to super class
> initializers. So, a subclass would have a setup block that is called after
> the setup block for the super class is called.
>
> I’m not sure what the best way to implement this would be and I do not
> have intimate knowledge of swift’s compilation process. However, if I were
> to hack it together I would create an intermediate representation that
> would create something like the following:
>
> class MyButton: UIButton {
>     override init(frame: CGRect) {
>         super.init(frame: frame)
>         defer {
>             setup()
>         }
>     }
>
>     convenience init() {
>         self.init(frame: CGRect.zero)
>     }
>
>
>     required init?(coder aDecoder: NSCoder) {
>         super.init(coder: aDecoder)
>         defer {
>             setup()
>         }
>     }
>
>     // This should be named something that does not conflict
> with function names that are already defined
>     private func setup() {
>         // Setup for custom class
>     }
> }
>
> The defer block is not necessary but it does add an addition layer of
> redundancy and makes the feature more resilient to change. You should also
> take note that setup is not called within the convenience initializer
> because setup will be called within the non-convenience initializer.
>
> Thank you everyone for your time, I look forward to hearing everyones
> feedback.
>
> -Andrew Arnopoulos
> _______________________________________________
> swift-evolution mailing list
> swift-evolution at swift.org
> https://lists.swift.org/mailman/listinfo/swift-evolution
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20161119/b185d959/attachment.html>


More information about the swift-evolution mailing list