<div dir="ltr">I feel like this would be an unexpected way of doing things.<div><br></div><div>Why would I want to separate my set-up code from my init() without any immediately obvious link between the two?</div><div><br></div><div>If your init() is getting unwieldy, perhaps a cleaner solution is to simply decompose some of the setting up into smaller (private) methods that are then called by the init()? At least when it is done this way, you can immediately see that other stuff happens from within the init() method without having to think about whether a will/didSet might have been called on a property.</div><div><br></div></div><div class="gmail_extra"><br><div class="gmail_quote">On Thu, Dec 24, 2015 at 6:39 AM, shengjia wang via swift-evolution <span dir="ltr"><<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div>Hi,</div><div><br></div><div>You are saying: <i>"Because you can probably just put most of that code at the end of your initialiser"</i>. I see.. and this proposal is exactly about how to avoid this situation.</div><div><br></div>I'm saying it would be neat if we can band some side effects once we set a `let` property. Example:<div><br></div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)"> let</span> view: <span style="color:rgb(112,61,170)">UIView</span> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">didSet</span> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> view.background = <span style="color:rgb(112,61,170)">UIColor</span>.blackColor()</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)"><span style="color:rgb(0,0,0)"> </span><span style="color:rgb(79,129,135)">view</span><span style="color:rgb(0,0,0)">.</span>translatesAutoresizingMaskIntoConstraints</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">let</span> scrollView: <span style="color:rgb(112,61,170)">UIScrollView</span> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">willSet</span> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> scrollView.removeObserver(<span style="color:rgb(187,44,162)">self</span>, forKeyPath: <span style="color:rgb(209,47,27)">"contentOffset"</span>)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">didSet</span> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> scrollView.addObserver(<span style="color:rgb(187,44,162)">self</span>, forKeyPath: <span style="color:rgb(209,47,27)">"contentOffset"</span>, options: .New, context: <span style="color:rgb(187,44,162)">nil</span>)</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)"> init</span>(targetScrollView: <span style="color:rgb(112,61,170)">UIScrollView</span>) {</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(79,129,135)">view</span> = <span style="color:rgb(112,61,170)">UIView</span>()</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> scrollView = targetScrollView</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">super</span>.<span style="color:rgb(187,44,162)">init</span>()</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"> </p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;min-height:13px"> // if we could put them into property observing ...</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> // view.background = <span style="color:rgb(112,61,170)">UIColor</span>.blackColor()</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(112,61,170)"><span style="color:rgb(0,0,0)"> // </span><span style="color:rgb(79,129,135)">view</span><span style="color:rgb(0,0,0)">.</span>translatesAutoresizingMaskIntoConstraints</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> // scrollView.<span style="color:rgb(61,29,129)">addObserver</span>(<span style="color:rgb(187,44,162)">self</span>, forKeyPath: <span style="color:rgb(209,47,27)">"contentOffset"</span>, options:<font color="#703daa">.New</font>, context: <span style="color:rgb(187,44,162)">nil</span>)</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> // ...</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo">
</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> }</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><br></p><p style="margin:0px;line-height:normal">We can extract the "setup property" step from init method and separate them for all different properties just after the property be initialised. Otherwise, we have to either mix them into the init method or change `let` to `var`. Both are doable but not ideal in my opinion.</p><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="font-family:arial,sans-serif;font-size:small"><br></span></p><p style="margin:0px;line-height:normal">By the way, the principal of this idea is similar to <a href="https://twitter.com/jesse_squires/status/626264940450480128" target="_blank">another approach for IBOutlet property</a> :</p><p style="margin:0px;line-height:normal"><br></p><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><span style="color:rgb(41,47,51);font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;white-space:pre-wrap;background-color:rgb(245,248,250)">Use </span><strong style="color:rgb(41,47,51);font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;white-space:pre-wrap">didSet</strong><span style="color:rgb(41,47,51);font-family:'Helvetica Neue',Helvetica,Arial,sans-serif;white-space:pre-wrap;background-color:rgb(245,248,250)"> on your IBOutlets to configure views instead of cramming code into viewDidLoad. Much cleaner. Still called only once.</span></blockquote><div><br></div><div>- Victor Wang </div></div><div></div></div><div class="HOEnZb"><div class="h5"><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Dec 23, 2015 at 5:07 PM, Félix Cloutier <span dir="ltr"><<a href="mailto:felixcca@yahoo.ca" target="_blank">felixcca@yahoo.ca</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word">willSet and didSet are currently not even called from the init method. This also goes counter to the current property behaviors proposal (didGet and didSet would become part of that) because behaviors aren't planned for let properties.<div><br></div><div>You're saying you want it to happen as soon as it was set, but do you really need it "as soon as that" or can you afford to wait a little bit? Because you can probably just put most of that code at the end of your initializer, where it's guaranteed that the property has been set.<br><div><br><div>
<span style="border-collapse:separate;color:rgb(0,0,0);font-family:'Lucida Grande';font-style:normal;font-variant:normal;font-weight:normal;letter-spacing:normal;line-height:normal;text-align:auto;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px">Félix</span>
</div>
<br><div><blockquote type="cite"><div><div><div>Le 23 déc. 2015 à 10:22:46, shengjia wang via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> a écrit :</div><br></div></div><div><div><div><div dir="ltr"><div><br></div><div>Since swift v1.2, we can initialize `let` property in `init()` instead of being forced to give a value when declare it. This is great ! <br></div><div><br></div><div>But every time I run into the case such as the example below:</div><div><br></div><div>let view: UIView {</div><div> didSet {</div><div> /** </div><div> * This time, `view` did set ( a.k.a initialized in case of `let` property), so I want to bind some other actions just after, such as `setBackgroundColor`. But actually I can't, compiler will complain that `let` declaration can not be observing properties. So I have to either move all these "actions" to `init()` or change `view` to a `var` property which is not necessary at all.</div><div> */</div><div> }</div><div>}</div><div><br></div><div>Actually in swift, I think it's quite commun issue that people run into a large `init()` method. This approach could make it way better in most cases.</div><div><br></div><div>So, I'm wondering why not make `didSet` also available for `let` property, or maybe even better to add new keyword such as "didInit" which only get called for first set.</div><div><br></div><div>- Victor Wang</div></div>
</div></div><img src="https://u2002410.ct.sendgrid.net/wf/open?upn=iRI3beHTe3UxYAHTlV3lA38zIPfHMhyuRzgTmGKV6k4hWgQ7LZ7-2BWMRdXW5ysMCIHZFfUSVobq6HMsNSYzHc3V1qcmcu0ijmD4VuwnWEfIpCxIhMF1QoF1fAQih46hMUIDz96AIlkQgMMx1NEvV3YQAMeORgRPYyzw-2BGQozWLv583tnPyNdfEA5zEj-2FXriCkpWyKLZu6bl4vW2xFbdyf7lu-2BgY5pIYTthLI1cJaFwMY-3D" alt="" width="1" height="1" border="0" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important">
_______________________________________________<br>swift-evolution mailing list<br><a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a><br><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br></div></blockquote></div><br></div></div></div></blockquote></div><br></div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=mRLpYbA4m-2BLyaGP7FtCeCykDifghnRS7TPc68gnt3FmvjQUzZG-2FqoWPheE4WdAHLmucpbZiFMRv9aXdlMdLJk0oVCBKMc62VNRyxIDYfx5Y8UCrORWRAaAaofUgsicwpTmh6ydRL-2FOoDbXIMfKHpBJ8s7DA0TBZPM4amAyrTz1lj8X7xCceLS-2FjGylHnjZ2pLTaETrANMgCr5lMvPbCRSDQre9z5w6vRtyp6m2ja3-2B4-3D" alt="" width="1" height="1" border="0" style="min-height:1px!important;width:1px!important;border-width:0!important;margin-top:0!important;margin-bottom:0!important;margin-right:0!important;margin-left:0!important;padding-top:0!important;padding-bottom:0!important;padding-right:0!important;padding-left:0!important">
</div></div><br>_______________________________________________<br>
swift-evolution mailing list<br>
<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
<br></blockquote></div><br></div>