<html><head><style>
body {
        font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
        padding:1em;
        margin:auto;
        background:#fefefe;
}

h1, h2, h3, h4, h5, h6 {
        font-weight: bold;
}

h1 {
        color: #000000;
        font-size: 28pt;
}

h2 {
        border-bottom: 1px solid #CCCCCC;
        color: #000000;
        font-size: 24px;
}

h3 {
        font-size: 18px;
}

h4 {
        font-size: 16px;
}

h5 {
        font-size: 14px;
}

h6 {
        color: #777777;
        background-color: inherit;
        font-size: 14px;
}

hr {
        height: 0.2em;
        border: 0;
        color: #CCCCCC;
        background-color: #CCCCCC;
    display: inherit;
}

p, blockquote, ul, ol, dl, li, table, pre {
        margin: 15px 0;
}

a, a:visited {
        color: #4183C4;
        background-color: inherit;
        text-decoration: none;
}

#message {
        border-radius: 6px;
        border: 1px solid #ccc;
        display:block;
        width:100%;
        height:60px;
        margin:6px 0px;
}

button, #ws {
        font-size: 12 pt;
        padding: 4px 6px;
        border-radius: 5px;
        border: 1px solid #bbb;
        background-color: #eee;
}

code, pre, #ws, #message {
        font-family: Monaco;
        font-size: 10pt;
        border-radius: 3px;
        background-color: #F8F8F8;
        color: inherit;
}

code {
        border: 1px solid #EAEAEA;
        margin: 0 2px;
        padding: 0 5px;
}

pre {
        border: 1px solid #CCCCCC;
        overflow: auto;
        padding: 4px 8px;
}

pre > code {
        border: 0;
        margin: 0;
        padding: 0;
}

#ws { background-color: #f8f8f8; }


.bloop_markdown table {
border-collapse: collapse;  
font-family: Helvetica, arial, freesans, clean, sans-serif;  
color: rgb(51, 51, 51);  
font-size: 15px; line-height: 25px;
padding: 0; }

.bloop_markdown table tr {
border-top: 1px solid #cccccc;
background-color: white;
margin: 0;
padding: 0; }
     
.bloop_markdown table tr:nth-child(2n) {
background-color: #f8f8f8; }

.bloop_markdown table tr th {
font-weight: bold;
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }

.bloop_markdown table tr td {
border: 1px solid #cccccc;
margin: 0;
padding: 6px 13px; }

.bloop_markdown table tr th :first-child, table tr td :first-child {
margin-top: 0; }

.bloop_markdown table tr th :last-child, table tr td :last-child {
margin-bottom: 0; }

.bloop_markdown blockquote{
  border-left: 4px solid #dddddd;
  padding: 0 15px;
  color: #777777; }
  blockquote > :first-child {
    margin-top: 0; }
  blockquote > :last-child {
    margin-bottom: 0; }

code, pre, #ws, #message {
    word-break: normal;
    word-wrap: normal;
}

hr {
    display: inherit;
}

.bloop_markdown :first-child {
    -webkit-margin-before: 0;
}

code, pre, #ws, #message {
    font-family: Menlo, Consolas, Liberation Mono, Courier, monospace;
}


.send { color:#77bb77; }
.server { color:#7799bb; }
.error { color:#AA0000; }</style></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="bloop_markdown"><p>Hello Evolution,</p>

<p>I’d like to pitch a new idea and see where it would go. Recently I tapped into a small trap and just now realized that even that <code>non-escaping</code> should have been the default for closures (SE–0103) there is an exception for that. Apparently generics don’t follow that rule and a closure like </p>

<p><code>Optional&lt;() -&gt; Void&gt;</code> or simply <code>(() -&gt; Void)?</code> </p>

<p>is still escaping by default. But that was the half of the story yet. As we all know and “love” reference lists inside closures, methods don’t have any and we have to wrap method calls into a weak referenced closure </p>

<p><code>{ [weak self] in self.foo() }</code> </p>

<p>to avoid strong reference cycles. Maybe you already guess it, I accidentally didn’t and tapped into the land of strong reference cycles yet again on my journey.</p>

<p>I’d like to pitch a new way, more like a new type behavior, for closures on how they could be used differently in order to avoid strong reference cycles but also providing the ability to use methods without any need to wrap them.</p>

<p>Here is a simple code snippet using RxSwift, which will recreate my issue:</p>

<pre><code class="swift">import RxSwift

let test = PublishSubject&lt;Void&gt;()

class A {

    let disposeBag = DisposeBag()

    func foo() {
        test.asObservable()
            .subscribe(onNext: self.bar) // The issue is here
            .disposed(by: self.disposeBag)
    }

    func bar() { print("works") }
}

let a = A()
a.foo()

test.onNext(()) // Testing if it works
test.onCompleted() // Some RxSwift stuff
</code></pre>

<p>In this case by passing directly the method <code>self.bar</code> we’re capturing <code>self</code>, which in this situation isn’t our intention at all. To avoid this issue we can simply wrap the method call into closure:</p>

<p><code>.subscribe(onNext: { [unowned self] in self.bar() })</code></p>

<p>(It’s safe to make it unowned because the dispose bag is a member of <code>self</code>.)</p>

<hr>

<p>What if we had the ability for weak or unowned closures? By that I don’t mean weak/unowned references to the closures themselves, because they are also reference types, but an invalidation behavior for the whole closure based on the _captured_ references. For instance:</p>

<p><code>let closure1: weak (() -&gt; Void)? = { self.doWhatever() }</code></p>

<p><code>let closure2: weak (() -&gt; Void)? = self.doWhatever</code></p>

<p>If one would now try to call the <code>closure</code>, first it will check if all the captured objects are still available or not, if not the whole closure in this case will simply become <code>nil</code> and won’t execute. In case of unowned closures it will trap. Furthermore it will support the general meaning of <code>weak/unowned</code> and will not increase the reference counter for *captured objects*.</p>

<p>As you have already noticed, in this case the convention is slightly different because we must carry the behavior directly with the type.</p>

<p><code>func subscribe(onNext: weak ((Swift.E) -&gt; Void)?)</code> </p>

<p>If the way of my thinking is correct this idea _could maybe_ fade out the very common <code>[weak self] in guard let strongSelf = self …</code> pattern. </p>

<hr>

<p>I personally cannot tell all the technical difficulties this idea might have, but that’s what the evolution list is for, to collaboratively flesh out the ideas if they are worth it.</p>

<hr>

<p>If something like this could be possible it’s probably worth noting that we might also be able to introduce something like <code>@autoclosure(weak/unowned)</code> to Swift for consistency.</p>

<p></p></div><div class="bloop_original_html"><style>body{font-family:Helvetica,Arial;font-size:13px}</style><div id="bloop_customfont" style="font-family:Helvetica,Arial;font-size:13px; color: rgba(0,0,0,1.0); margin: 0px; line-height: auto;"><br></div><br><div id="bloop_sign_1497112926484879104" class="bloop_sign"><div style="font-family:helvetica,arial;font-size:13px">--&nbsp;<br>Adrian Zubarev<br>Sent with Airmail</div></div></div><div class="bloop_markdown"><p></p></div></body></html>