<div dir="ltr">Why isn't self unowned by default? Seems like that would fix all kinds of problems including being a novice.<div><br></div><div><div>Here's an example of a case where you need a strong self. Imagine that <span style="font-family:Menlo;font-size:11px">[unowned </span><span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)">self</span><span style="font-family:Menlo;font-size:11px">] </span>is the default and the programmer made the mistake of forgetting to use <span style="font-family:Menlo;font-size:11px">[strong </span><span style="font-family:Menlo;font-size:11px;color:rgb(187,44,162)">self</span><span style="font-family:Menlo;font-size:11px">]</span> .</div><div><br></div><div><p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"><span style="color:rgb(187,44,162)">class</span> ClosureFactory {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">let</span> s:<span style="color:rgb(112,61,170)">String</span></p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">init</span>(<span style="color:rgb(187,44,162)">_</span> s:<span style="color:rgb(112,61,170)">String</span>) { <span style="color:rgb(187,44,162)">self</span>.<span style="color:rgb(79,129,135)">s</span> = s }</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">func</span> writeln() -> () -> <span style="color:rgb(112,61,170)">Void</span> {</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo"> <span style="color:rgb(187,44,162)">return</span> {[unowned <span style="color:rgb(187,44,162)">self</span>] <span style="color:rgb(187,44,162)">in</span> <span style="color:rgb(61,29,129)">print</span>(<span style="color:rgb(187,44,162)">self</span>.<span style="color:rgb(79,129,135)">s</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)">let</span> writer = <span style="color:rgb(79,129,135)">ClosureFactory</span>(<span style="color:rgb(209,47,27)">"hi"</span>).<span style="color:rgb(49,89,93)">writeln</span>()</p>
<p style="margin:0px;font-size:11px;line-height:normal;font-family:Menlo;color:rgb(79,129,135)">writer<span style="color:rgb(0,0,0)">()</span></p></div><div><span style="color:rgb(0,0,0)"><br></span></div><div><span style="color:rgb(0,0,0)">The program crashes. Wouldn't this be better than having a default that makes it easy to write memory leaks? I'd much rather be fixing a bug in code I wrote 5 minutes ago than 5 months ago. Especially a memory leak.</span></div></div><div><span style="color:rgb(0,0,0)"><br></span></div><div><span style="color:rgb(0,0,0)">-david </span><a href="https://github.com/AE9RB/SwiftGL">https://github.com/AE9RB/SwiftGL</a></div><div><span style="color:rgb(0,0,0)"><br></span></div><div><br></div><div><br></div><div class="gmail_extra"><div class="gmail_quote">On Sun, Jan 17, 2016 at 11:57 AM, Jacob Bandes-Storch via swift-users <span dir="ltr"><<a href="mailto:swift-users@swift.org" target="_blank">swift-users@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">I also noticed this problem with nested functions recently:<br><div><div><br></div><div><font face="monospace, monospace"> class Foo {</font></div><div><font face="monospace, monospace"> </font></div><div><font face="monospace, monospace"> var handler: (() -> Void)?</font></div><div><font face="monospace, monospace"> </font></div><div><font face="monospace, monospace"> func noop() {}</font></div><div><font face="monospace, monospace"> </font></div><div><font face="monospace, monospace"> func setup() {</font></div><div><font face="monospace, monospace"> // <b>error:</b></font></div><div><font face="monospace, monospace"> handler = { noop() }</font></div><div><font face="monospace, monospace"> </font></div><div><font face="monospace, monospace"> // <b>no error:</b></font></div><div><font face="monospace, monospace"> handler = noop</font></div><div><font face="monospace, monospace"> </font></div><div><font face="monospace, monospace"> // <b>no error:</b></font></div><div><font face="monospace, monospace"> func innerFunc() { noop() }</font></div><div><font face="monospace, monospace"> handler = { innerFunc() }</font></div><div><font face="monospace, monospace"> handler = innerFunc</font></div><div><font face="monospace, monospace"> }</font></div><div><font face="monospace, monospace"> }</font></div></div><div class="gmail_extra"><br clear="all"><div><div><div dir="ltr"><div>Jacob<br></div></div></div></div>
<br><div class="gmail_quote"><div><div class="h5">On Sun, Jan 17, 2016 at 11:06 AM, Joshua Scott Emmons via swift-users <span dir="ltr"><<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>></span> wrote:<br></div></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div><div class="h5"><div style="word-wrap:break-word"><font color="#323333">There's a test case demonstrating what I'm about to talking about: <a href="https://gist.github.com/jemmons/6f668006fa2712a84807" target="_blank">https://gist.github.com/jemmons/6f668006fa2712a84807</a></font><div><font color="#323333"><br></font></div><div><font color="#323333">But here's the nut of it. Given a class like:</font></div><div><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap"><br></span></div><div><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap"><span>class</span><span style="color:rgb(51,51,51);background-color:rgb(255,255,255)"> Foo {</span> </span></div><div><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap"> </span><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">var</span><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"> handler: (()</span><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">-></span><span style="color:rgb(0,134,179);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">Void</span><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)">)?</span></div><div><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap"> func</span><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"> </span><span style="color:rgb(121,93,163);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">noop</span><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)">(){}</span></div><div><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"> ...</span></div><div><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)">}</span></div><div><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"><br></span></div><div><span style="color:rgb(51,51,51);white-space:pre-wrap;background-color:rgb(255,255,255)">If somewhere in this class I do something like:</span></div><div><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"><br></span></div><div><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)">handler </span><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">=</span><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"> { </span><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">self</span><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">.</span><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)">noop() }</span></div><div><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"><br></span></div><div><span style="color:rgb(51,51,51);white-space:pre-wrap;background-color:rgb(255,255,255)">I've created a retain cycle because <font face="Menlo">handler</font> holds a strong reference to a closure which holds a strong reference to <font face="Menlo">self</font> which holds a strong reference to a closure that…</span></div><div><span style="color:rgb(51,51,51);white-space:pre-wrap;background-color:rgb(255,255,255)"><br></span></div><div><font color="#333333"><span style="white-space:pre-wrap;background-color:rgb(255,255,255)">In fact, my understanding is Swift's requirement that </span></font><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">self</span><span style="color:rgb(51,51,51);white-space:pre-wrap;background-color:rgb(255,255,255)"> be called out here explicitly is to highlight this danger. </span></div><div><span style="color:rgb(51,51,51);white-space:pre-wrap;background-color:rgb(255,255,255)"><br></span></div><div><span style="color:rgb(51,51,51);white-space:pre-wrap;background-color:rgb(255,255,255)">Swift makes it easy to fix the problem with a capture list:</span></div><div><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"><br></span></div><div><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)">handler </span><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">=</span><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"> { [</span><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">unowned</span><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"> </span><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">self</span><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)">] </span><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">in</span><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"> </span><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">self</span><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">.</span><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)">noop() }</span></div><div><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"><br></span></div><div><font color="#333333"><span style="white-space:pre-wrap;background-color:rgb(255,255,255)">So far, so good. But what if I do something daft like assign <font face="Menlo">noop</font> directly:</span></font></div><div><font color="#333333"><span style="white-space:pre-wrap;background-color:rgb(255,255,255)"><br></span></font></div><div><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)">handler </span><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">=</span><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"> noop</span></div><div><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"><br></span></div><div><font color="#333333"><span style="white-space:pre-wrap;background-color:rgb(255,255,255)">This causes a retain loop for all the same reasons as our original example, but there's no </span></font><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">self</span><span style="white-space:pre-wrap;background-color:rgb(255,255,255);color:rgb(51,51,51)"> call-out to warn us of impending doom, and no support for some kind of capture list to fix the issue.</span></div><div><span style="white-space:pre-wrap;background-color:rgb(255,255,255);color:rgb(51,51,51)"><br></span></div><div><span style="background-color:rgb(255,255,255)"><font color="#333333"><span style="white-space:pre-wrap">Is there any possibility of requiring "self" here? As in: "</span></font></span><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)">handler </span><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">=</span><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"> </span><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">self</span><span style="color:rgb(167,29,93);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap">.</span><span style="color:rgb(51,51,51);font-family:Consolas,'Liberation Mono',Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)">noop" </span><span style="color:rgb(51,51,51);white-space:pre-wrap;background-color:rgb(255,255,255)">for example? And is there any way of specifying how we want self to be retained here?</span></div><div><span style="color:rgb(51,51,51);white-space:pre-wrap;background-color:rgb(255,255,255)"><br></span></div><div><span style="color:rgb(51,51,51);white-space:pre-wrap;background-color:rgb(255,255,255)"><br></span></div><div><span style="color:rgb(51,51,51);white-space:pre-wrap;background-color:rgb(255,255,255)">Cheers,</span></div><div><span style="color:rgb(51,51,51);white-space:pre-wrap;background-color:rgb(255,255,255)">-jemmons</span></div></div><br></div></div></blockquote></div></div></div></blockquote></div><br></div></div>