<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"><style type="text/css">body { background: rgba(255, 255, 255, 255); }</style></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><blockquote type="cite" class="">On Sep 12, 2016, at 4:01 PM, Joe Groff <<a href="mailto:jgroff@apple.com" class="">jgroff@apple.com</a>> wrote:<br class=""><br class=""><br class=""><blockquote type="cite" class="">On Sep 12, 2016, at 12:24 PM, Paul Cantrell <<a href="mailto:cantrell@pobox.com" class="">cantrell@pobox.com</a>> wrote:<br class=""><br class="">In Swift 2, this declaration ensured that callers used only objects as owners:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func addObserver(observer: ResourceObserver, owner: AnyObject)<br class=""><br class="">In Swift 3, however, an unsuspecting called can pass a struct as an owner. Swift helpfully wraps it in a _SwiftValue, the _SwiftValue is only weakly referenced so it’s immediately deallocated, and so the observer is immediately discarded. It’s nonsensical. The compiler should be able to detect & prevent this.<br class=""><br class="">What I want is:<br class=""><br class=""><span class="Apple-tab-span" style="white-space:pre">        </span>func addObserver(observer: ResourceObserver, owner: AnyObjectForRealNotJustAValueWrapper)<br class=""><br class="">AFAIK, this is impossible in Swift 3. Or is it?<br class=""></blockquote><br class="">If you declare the API as taking AnyObject in Swift, this should work *better* in Swift 3, since it is no longer possible to pass non-object value types to an AnyObject API by implicit conversion. If the API came from Objective-C, and uses `id` there, you could perhaps hide the `Any` version that gets imported and drop an AnyObject-taking version on top of it in a Swift overlay. I agree that we ought to have a more general feature in ObjC to say "no, really, this needs to be a reference type", but I think that's orthogonal to Charles' original request.</blockquote><div class=""><br class=""></div>Ah, you’re quite right. Verified it, and it works exactly as you describe. Of course. I’ve been worrying my little head over nothing. Thanks for clearing that up!<div class=""><br class=""></div><div class="">On investigating, turns out I’d misunderstood the larger situation from a more localized Swift 3 change in an internal utility class:</div><div class=""><br class=""></div><div class=""><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #b7bcb3" class="">/**</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(183, 188, 179);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> A reference that can switched between behaving as a strong or a weak ref to an object,</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(183, 188, 179);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> and can also hold a non-object type.</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(183, 188, 179); min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(183, 188, 179);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> - If the value is an object, then...</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(183, 188, 179);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> - ...if strong == true, then StrongOrWeakRef holds a strong reference to value.</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(183, 188, 179);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> - ...if strong == false, then StrongOrWeakRef holds a weak reference to value.</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(183, 188, 179);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(183, 188, 179);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> - If the value is of a value type, then...</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(183, 188, 179);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> - ...if strong == true, then StrongOrWeakRef holds the structure.</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(183, 188, 179);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> - ...if strong == false, then StrongOrWeakRef immediately discards the structure.</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(183, 188, 179);" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> */</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">internal</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">struct</span><span style="font-variant-ligatures: no-common-ligatures" class=""> StrongOrWeakRef<T> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">private</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> strongRef: </span><span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">?</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">private</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">weak</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> weakRef: </span><span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">AnyObject</span><span style="font-variant-ligatures: no-common-ligatures" class="">?</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> value: </span><span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">? {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">strongRef</span><span style="font-variant-ligatures: no-common-ligatures" class=""> ?? (</span><span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">weakRef</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">as</span><span style="font-variant-ligatures: no-common-ligatures" class="">? </span><span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">)</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">init</span><span style="font-variant-ligatures: no-common-ligatures" class="">(</span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">_</span><span style="font-variant-ligatures: no-common-ligatures" class=""> value: </span><span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">T</span><span style="font-variant-ligatures: no-common-ligatures" class="">) {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">strongRef</span><span style="font-variant-ligatures: no-common-ligatures" class=""> = value</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; color: rgb(102, 139, 73);" class=""><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">weakRef</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> = value </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">as</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">AnyObject</span><span style="font-variant-ligatures: no-common-ligatures; color: #000000" class="">? </span><span style="font-variant-ligatures: no-common-ligatures" class="">// ← <b class="">was `as? AnyObject` in Swift 2</b></span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo; min-height: 13px;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""></span><br class=""></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">var</span><span style="font-variant-ligatures: no-common-ligatures" class=""> strong: </span><span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">Bool</span><span style="font-variant-ligatures: no-common-ligatures" class=""> {</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">get</span><span style="font-variant-ligatures: no-common-ligatures" class=""> { </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">return</span><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">strongRef</span><span style="font-variant-ligatures: no-common-ligatures" class=""> != </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">nil</span><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">set</span><span style="font-variant-ligatures: no-common-ligatures" class=""> { </span><span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">strongRef</span><span style="font-variant-ligatures: no-common-ligatures" class=""> = newValue ? </span><span style="font-variant-ligatures: no-common-ligatures; color: #587ea8" class="">value</span><span style="font-variant-ligatures: no-common-ligatures" class=""> : </span><span style="font-variant-ligatures: no-common-ligatures; color: #323e7d" class="">nil</span><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div><div style="margin: 0px; font-size: 11px; line-height: normal; font-family: Menlo;" class=""><span style="font-variant-ligatures: no-common-ligatures" class=""> }</span></div></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class=""><br class=""></span></div><div class=""><span style="font-variant-ligatures: no-common-ligatures" class="">The marked line used to be able to just leave </span><span style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(88, 126, 168);" class="">weakRef</span> nil when given a value type. Now, because the <span style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(50, 62, 125);" class="">as</span><span style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;" class=""> </span><span style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures; color: rgb(88, 126, 168);" class="">AnyObject</span><span style="font-family: Menlo; font-size: 11px; font-variant-ligatures: no-common-ligatures;" class="">?</span> coercion always succeeds, it performs an unnecessary heap allocation (I think?) for a _SwiftValue that’s instantly discarded. The semantics don’t change, just the performance penalty.</div><div class=""><br class=""></div><div class="">That’s a case for Charles’s “is it really an object?” Unless I’m off in the weeds again. Hardly the end of the world though!</div><div class=""><br class=""></div><div class="">Cheers, P</div><div class=""><br class=""></div></body></html>