<div style="white-space:pre-wrap">I would like to also note that referencing an object (whether self or otherwise) does not necessarily create a permanent retain cycle. Only long-lived closures will cause these issues. In many other cases, retaining objects inside a closure is actually what you want, to ensure they're still alive by the time the closure is called. <br>In general, no matter what the default is, my hunch is that this is one of those "hard problems" (essential complexity: <a href="https://en.m.wikipedia.org/wiki/No_Silver_Bullet">https://en.m.wikipedia.org/wiki/No_Silver_Bullet</a>), and one must think about the lifetime semantics of the constructions in their code and the APIs they're using to understand the implications of using weak or strong captures, and whether they will cause retain cycles or premature deallocations. <br></div><div class="gmail_quote"><div dir="ltr">On Tue, Dec 8, 2015 at 4:08 AM ilya via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr">I don't think this would satisfy the principle of "working as expected", e.g.:<div><br></div><div>class Computer {</div><div> func compute() -> Int { ... }</div><div>}</div><div><br></div><div>func test() {</div><div> </div><div> let c = Computer()</div><div><br></div><div> // Expected: the closure executes in the background</div><div> dispatch_async(...) {<br></div><div><br></div><div> let computed = c.compute()</div><div> print(computed)</div><div><br></div><div> let computed2 = c.compute()</div><div> print(computed2)</div><div> }</div><div><br></div><div>}</div><div><br></div><div>Actual result if the proposal passes: the closure will not compile as c will be optional.</div><div><br></div><div>Moreover, you'll have some beginners who will fix it with</div><div><br></div><div><div> dispatch_async(...) {</div><div><br></div><div> if let computed = c?.compute() {</div><div> print(computed)</div><div> }</div><div><br></div><div> if let computed2 = c?.compute() {</div><div> print(computed2)</div><div> }</div><div> }</div></div><div><br></div><div>which has entirely different logic, as now any of those situations is possible:</div><div>(1) both computed and computed2 are printed</div><div>(2) none of those is printed</div><div>(3) only computed is printed</div></div><div dir="ltr"><div> <br><div class="gmail_quote"><div dir="ltr">On Tue, Dec 8, 2015 at 14:15 Andrew Bennett via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>> wrote:<br></div><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"><div dir="ltr">From <a href="https://swift.org/about/" target="_blank">https://swift.org/about/</a>: "The most obvious way to write code should also behave in a safe manner."<div><br></div><div>To this end I think that closures should capture references types weakly by default. Pretty much the only way I know of to (easily) create memory issues with pure swift is to capture a strong reference in a closure.</div><div><br></div><div>I think with consideration when designing asynchronous APIs this could be quite painless.</div><div><br></div><div>Cases weak may be excluded:</div><div> * If the closure is @noescape<br></div><div> * If the object's lifetime is provably limited to the block</div><div> * If it's a value type</div><div><br></div><div>I think the upsides by far outweigh the downsides.</div><div><br></div><div>Upside:</div><div> * no more surprises</div><div> * safer code</div><div><br></div><div>Downsides:</div><div> * You may sometimes have to use optional chaining or similar to resolve a weak reference.</div><div> * Beginners need to understand optionals, but they're likely to do so before learning blocks.</div><div> * There's probably a few edge cases I haven't explored, and a few more here:<br></div><div><br></div><div>class Test {</div><div> func doSomething(v: Int) { ... }</div><div> func async(callback: Int->Void) {</div><div> doWork { value in</div><div> callback?(value)</div><div> }</div><div> }</div><div>}</div><div><br></div><div>self.test = Test()</div><div>self.test.async(test.doSomething) // what is the lifetime of test.doSomething?</div><div><br></div></div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=1p9Jer2O6jVE9KWvo-2B9iUaEyN8slp4IizyiLwsfp54PuMg50nS7bLpj1hyi5ExO3KdQydgBLV4xISYIIJIwALHvF7G7k11o272bL8praP9j1BmsJ5fYEJ-2B2SB7BnqI-2B5Uo1HPbI0UQOtY-2B97gGyyLuDDmlSkpnr-2BO-2B7ycBumg9jiZfZLtn6VL66SRJ31b924zJo85AonRKcLwQTcxJ19x7GHbutZHWDQdaKSDHzm-2BtI-3D" alt="" width="1" height="1" border="0" style="min-height:1px!important;width:1px!important;border-width:0px!important;margin:0px!important;padding:0px!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" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div></div></div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=EmLgVGNgdilXys3cXWyAWvOFC2-2FejnHkMVv8PyEdfbq5T3M7j77pO0rB7DE8VGdjgPGgvqj-2FVIfHMKmePDtux0zf0upfljEA0o1UrWYRR8We8ueIWSprtC1rivwRC8F8kEmbP6D-2FkWyVytZ-2BRqDMNOQqUDeB9J6nLWBXeK9w1YGpkwpzm5e1hdgdfrgeBOg2IsIFGKcXz9feGLFwUljYZQHVuQjEbbHkWyBYHYh4c2M-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" rel="noreferrer" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br>
</blockquote></div><div dir="ltr">-- <br></div>Javier Soto