<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="">Using box types solves the portability problems, but it still means O(n) access for clients who want to access the non-boxed values directly. Additionally, these objects aren’t automatically removed from the collection when their values are nil-ed out, which is unfortunate.<div class=""><br class=""></div><div class="">Side note: this is the route I originally tried to take, but unfortunately the Swift doesn’t work well with weak references to protocol types…</div><div class=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 10, 2015, at 3:01 PM, Tommy van der Vorst &lt;<a href="mailto:tommy@pixelspark.nl" class="">tommy@pixelspark.nl</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class="">Hi Riley,</div><div class=""><br class=""></div><div class="">Have you tried using an array of structs that in turn hold weak references to your objects? Something like this should work:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">public</span> <span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">class</span> Weak&lt;T: AnyObject&gt;: <span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">NSObject</span> {</div><div style="margin: 0px; line-height: normal; color: rgb(4, 51, 255);" class=""><span style="" class=""><span class="Apple-tab-span" style="white-space:pre">        </span></span>public<span style="" class=""> </span>private(set)<span style="" class=""> </span>weak<span style="" class=""> </span>var<span style="" class=""> value: </span><span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span><span style="" class="">?</span></div><div style="margin: 0px; line-height: normal; min-height: 13px;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">public</span> <span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">init</span>(<span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">_</span> value: <span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">T</span>?) {</div><div style="margin: 0px; line-height: normal;" class=""><span class="Apple-tab-span" style="white-space:pre">                </span><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">self</span>.<span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">value</span> = value</div><div style="margin: 0px; line-height: normal;" class=""><span class="Apple-tab-span" style="white-space:pre">        </span>}</div><div style="margin: 0px; line-height: normal;" class="">}</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class=""><div style="margin: 0px; line-height: normal;" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #0433ff" class="">let</span> weakFoo: [<span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Weak</span>&lt;<span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Foo</span>&gt;] = [Weak&lt;<span style="font-variant-ligatures: no-common-ligatures; color: #3495af" class="">Foo</span>&gt;(foo), ...]</div></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">Comes with the overhead of one extra object instantiated per element, but perhaps this is acceptable for your use case.</span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-family: Helvetica; font-size: 12px;" class=""><br class=""></span></div><div style="margin: 0px; line-height: normal;" class=""><span style="font-family: Helvetica; font-size: 12px;" class="">/T</span></div></div></div><br class=""><div class=""><blockquote type="cite" class=""><div class="">Op 10 dec. 2015, om 23:55 heeft Riley Testut via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; het volgende geschreven:</div><br class="Apple-interchange-newline"><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">In multiple places in my projects, I essentially recreate the “multiple observer” pattern used by NSNotificationCenter. Originally this was implemented by simply maintaining an array of observers, and adding to/removing from it as necessary. However, this had the unintended side effect of maintaining a strong reference to the observers, which in many cases is undesirable (for the same reasons it’s common to mark delegate properties as weak).<div class=""><br class=""></div><div class="">Now, I’m using a private NSHashTable instance, and expose the observers as public API by creating a public computed property which essentially returns an array derived from the NSHashTable like so:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">public</span><span style="" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">var</span><span style="" class=""> receivers: [</span>GameControllerReceiverType<span style="" class="">] {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(0, 132, 0);" class=""><span style="" class="">&nbsp; &nbsp; </span>// self.privateReceivers.allObjects as! [GameControllerReceiverType] crashes Swift :(</div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(79, 129, 135);" class=""><span style="" class="">&nbsp; &nbsp; </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">return</span><span style="" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">self</span><span style="" class="">.</span>privateReceivers<span style="" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #703daa" class="">allObjects</span><span style="" class="">.</span><span style="font-variant-ligatures: no-common-ligatures; color: #3d1d81" class="">map</span><span style="" class="">({ $0 </span><span style="font-variant-ligatures: no-common-ligatures; color: #bb2ca2" class="">as</span><span style="" class="">! </span>GameControllerReceiverType<span style="" class=""> })</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class="">}</div></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">This workaround works, but is undesirable for a number of reasons. Most notably:</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">• NSHashTable is not a native Swift collection, and is also not in the Foundation Swift port, so it is not portable to other systems.</div><div style="margin: 0px; line-height: normal;" class="">• It also has not yet been annotated with generics, so it loses the nice type safety of other Swift collections. Because of this, I have to map the objects to the appropriate type before returning the allObjects array, which runs in O(n) time instead of O(1).</div><div style="margin: 0px; line-height: normal;" class="">• It’s repetitive. For every type that wants to implement this pattern, they must maintain both a public computed method and a private NSHashTable instance. This gets worse when this should be part of a protocol; there’s no way to enforce that each type conforming to it has a NSHashTable, while also keeping that information private from the consumer of the API.</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">I think native swift collections with support for weak references for their contents would be very useful, and in more places than just listed above. I don’t think Array could be easily extended to support it (what happens if a value is released? does everything shift down? do they keep their indices?), but Set and Dictionary (where the keys and/or values could be weak, akin to&nbsp;NSMapTable) would be good candidates IMO.</div><div style="margin: 0px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; line-height: normal;" class="">Thoughts?</div>
<img src="https://u2002410.ct.sendgrid.net/wf/open?upn=YfJegnDVHFjciv1mJPW79zu0hcjAYJ-2BpFoOAdq9R1JegFoDiuAY72lo9JBPV9zgQfc4e6VQJ2kVBrFKRr6DXU69HIvGPIKP3Z3eDnjZEShrasSIbq1T78yYiMv5tnYs0IkNFdTO2nG47SXXRVxqkzpMw9PAfXj7w8NXOKj4fA0fNKN1ewpqMjFY9yXrmgQl5JoULpM7xC7N44MTq5RejCf1WiNVps9aGnucVZ5TgUi4-3D" alt="" width="1" height="1" border="0" style="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;" class="">
</div>
_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class=""><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class=""></div></blockquote></div><br class=""></div></div></blockquote></div><br class=""></div></body></html>