<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div><blockquote type="cite" class=""><div class="">On 3 Mar 2017, at 22:14, Alex Johnson via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="WordSection1" style="page: WordSection1; font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);"><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class="">Hi list members,<o:p class=""></o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class=""><o:p class="">&nbsp;</o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class="">During code review today, I noticed a really subtle memory leak that looked like:<o:p class=""></o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class=""><o:p class="">&nbsp;</o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class="">&nbsp;&nbsp;&nbsp; self.relatedObject = RelatedObject(callback: relatedObjectDidFinish)<o:p class=""></o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class=""><o:p class="">&nbsp;</o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class="">Where `relatedObject` is a strong reference, `callback` is an escaping closure, and `relatedObjectDidFinish` is a method of `self`. From a memory management perspective, this code is equivalent to:<o:p class=""></o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class=""><o:p class="">&nbsp;</o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class="">&nbsp;&nbsp;&nbsp; self.relatedObject = RelatedObject(callback: { self.relatedObjectDidFinish })<o:p class=""></o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class=""><o:p class="">&nbsp;</o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class="">In the second example, an explicit `self.` is required. It’s my understanding that this is to highlight that the closure keeps a strong reference to `self`. But, when passing a method, there is no such requirement, which makes it easier to accidentally create a retain cycle.<o:p class=""></o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class=""><o:p class="">&nbsp;</o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class="">This made me wonder if an explicit `self.` should be required when passing a method as an escaping closure. And whether that would help in the same way that the explicit `self.` *inside* the closure is intended to.<o:p class=""></o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class=""><o:p class="">&nbsp;</o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class="">If it were required, the code in the first example would be:<o:p class=""></o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class=""><o:p class="">&nbsp;</o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class="">&nbsp;&nbsp;&nbsp; self.relatedObject = RelatedObject(callback: self.relatedObjectDidFinish)<o:p class=""></o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class=""><o:p class="">&nbsp;</o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class="">What do you think?<o:p class=""></o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class=""><o:p class="">&nbsp;</o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><b class=""><span style="font-size: 11pt;" class="">Alex Johnson<o:p class=""></o:p></span></b></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class=""><a href="mailto:ajohnson@walmartlabs.com" style="color: rgb(149, 79, 114); text-decoration: underline;" class=""><span style="color: rgb(5, 99, 193);" class="">ajohnson@walmartlabs.com</span></a><o:p class=""></o:p></span></div><div style="margin: 0in 0in 0.0001pt; font-size: 12pt; font-family: Calibri;" class=""><span style="font-size: 11pt;" class="">ajohnson on Slack</span><o:p class=""></o:p></div></div><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); float: none; display: inline !important;" class="">_______________________________________________</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" class=""><span style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255); float: none; display: inline !important;" class="">swift-evolution mailing list</span><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" class=""><a href="mailto:swift-evolution@swift.org" style="color: rgb(149, 79, 114); text-decoration: underline; font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" class="">swift-evolution@swift.org</a><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" style="color: rgb(149, 79, 114); text-decoration: underline; font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px; background-color: rgb(255, 255, 255);" class=""></div></blockquote></div><br class=""><div class=""><br class=""></div><div class="">+1</div><div class=""><br class=""></div><div class="">If you wrote it with a trailing closure, you would need to use ‘self’, so I think it’s reasonable to require it when passing the function as an escaping closure as well:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">self.relatedObject = RelatedObject { self.relatedObjectDidFinish() } // self required here</div><div class=""><br class=""></div></blockquote>Similarly, it would be nice if we had this convenient syntax for unowned function references:<div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">self.relatedObject = RelatedObject { [unowned self] in self.relatedObjectDidFinish() }</div><div class=""><br class=""></div></blockquote>would become:<br class=""><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><br class=""></div><div class="">self.relatedObject = RelatedObject(callback: (unowned self).relatedObjectDidFinish)</div><div class=""><br class=""></div></blockquote>- Karl</body></html>