<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: (() -&gt; 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">On Sun, Jan 17, 2016 at 11:06 AM, Joshua Scott Emmons via swift-users <span dir="ltr">&lt;<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a>&gt;</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"><font color="#323333">There&#39;s a test case demonstrating what I&#39;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&#39;s the nut of it. Given a class like:</font></div><div><span style="color:rgb(167,29,93);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap"><br></span></div><div><span style="color:rgb(167,29,93);font-family:Consolas,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">  </span><span style="color:rgb(167,29,93);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">var</span><span style="color:rgb(51,51,51);font-family:Consolas,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">-&gt;</span><span style="color:rgb(0,134,179);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">Void</span><span style="color:rgb(51,51,51);font-family:Consolas,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">  func</span><span style="color:rgb(51,51,51);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"> </span><span style="color:rgb(121,93,163);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">noop</span><span style="color:rgb(51,51,51);font-family:Consolas,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">=</span><span style="color:rgb(51,51,51);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"> { </span><span style="color:rgb(167,29,93);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">self</span><span style="color:rgb(167,29,93);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">.</span><span style="color:rgb(51,51,51);font-family:Consolas,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,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&#39;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&#39;s requirement that </span></font><span style="color:rgb(167,29,93);font-family:Consolas,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">=</span><span style="color:rgb(51,51,51);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"> { [</span><span style="color:rgb(167,29,93);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">unowned</span><span style="color:rgb(51,51,51);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"> </span><span style="color:rgb(167,29,93);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">self</span><span style="color:rgb(51,51,51);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)">] </span><span style="color:rgb(167,29,93);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">in</span><span style="color:rgb(51,51,51);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"> </span><span style="color:rgb(167,29,93);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">self</span><span style="color:rgb(167,29,93);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">.</span><span style="color:rgb(51,51,51);font-family:Consolas,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">=</span><span style="color:rgb(51,51,51);font-family:Consolas,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,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&#39;s no </span></font><span style="color:rgb(167,29,93);font-family:Consolas,&#39;Liberation Mono&#39;,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 &quot;self&quot; here? As in: &quot;</span></font></span><span style="color:rgb(51,51,51);font-family:Consolas,&#39;Liberation Mono&#39;,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,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">=</span><span style="color:rgb(51,51,51);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)"> </span><span style="color:rgb(167,29,93);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">self</span><span style="color:rgb(167,29,93);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap">.</span><span style="color:rgb(51,51,51);font-family:Consolas,&#39;Liberation Mono&#39;,Menlo,Courier,monospace;white-space:pre-wrap;background-color:rgb(255,255,255)">noop&quot; </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>_______________________________________________<br>
swift-users mailing list<br>
<a href="mailto:swift-users@swift.org" target="_blank">swift-users@swift.org</a><br>
<a href="https://lists.swift.org/mailman/listinfo/swift-users" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-users</a><br>
<br></blockquote></div><br></div></div>