<html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><br class=""><div><br class=""><blockquote type="cite" class=""><div class="">On Nov 29, 2017, at 2:07 PM, Riley Testut <<a href="mailto:rileytestut@gmail.com" class="">rileytestut@gmail.com</a>> 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=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Nov 9, 2017, at 9:01 AM, Philippe Hausler <<a href="mailto:phausler@apple.com" class="">phausler@apple.com</a>> 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; line-break: after-white-space;" class="">I have personally filed a few bugs on this; and I definitely consider it a bug that we cannot store Any in generics for objc. There are however some problem areas that might be worth considering while fixing this bug. </div></div></blockquote><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">1) We need to ensure this does not cause source churn - I would expect swift 4 to be source compatible with swift 5.</div></div></div></blockquote><div class=""><br class=""></div><div class="">Agreed. I'd be surprised if this <i class="">would</i> cause churn though, since this is effectively just loosening a restriction, and all existing use cases would still be allowed.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">2) There are a few cases that might be a bit cagey - you claim NSCache, but would it be surprising that the boxed object having no refs gets purged? How bout NSPointerArray? </div></div></div></blockquote><div class=""><br class=""></div><div class="">I agree there are certain cases where <i class="">true</i> reference semantics are important, and off the top of my head I can think of two (relatively easy) ways we could accommodate this:</div><div class=""><br class=""></div><div class="">1) The Objective-C class declaration explicitly specifies an upper-bound of NSObject (or NSObjectProtocol).</div><div class="">2) Add a new keyword (similar to existing __covariant and __contravariant keywords) such as __reference (where the final name would of course be bike-shedded)</div><div class=""><br class=""></div><div class="">I’m leaning towards an approach similar to 2) since 1) might be confusing to newcomers due to it seemingly have no purpose considering the NSObject constraint would implicitly there where using the generic class from Objective-C code.</div></div></div></div></blockquote><div><br class=""></div><div>Option 2 may take a lot of effort just as a heads up since that will mean that we would need to audit the entire macOS, iOS, tvOS, and watchOS SDKs and find any edge cases (my guess is very very few and perhaps only Foundation)</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><br class=""></div><div class="">I’m not familiar with NSCache’s internals, so I wasn’t aware references play a role in whether or not NSCache purges an object. That being said, I don’t think it would be surprising if NSCache purged a large Data value under memory pressure, as long as it didn’t affect any “copies” I had retrieved and was currently using. </div><div class=""><br class=""></div><div class="">As for NSPointerArray, we’d still need to get Objective-C generics for it first 😉 Though assuming that is added, the generic parameter would need to explicitly say it requires a reference.</div></div></div></div></blockquote><div><br class=""></div><div>NSMapTable or NSHashTable might be better examples; if the key or value is weakly stored the translated reference will drop off if the held structure is mutated.</div><div>e.g.</div><div><br class=""></div><div>var m = NSMapTable<NSString, NSData>(keyOptions: [.copyIn, .objectPersonality], valueOptions: [.weakMemory, .objectPersonality])<br class=""><br class="">var key = "hello" as NSString<br class="">var value = Data(bytes: [0, 1, 2, 3]) as NSData<br class=""><br class="">m.setObject(value, forKey: key)<br class=""><br class="">assert(m.object(forKey: key) != nil)</div><div><br class=""></div><div>That works as expected - so lets change it to a structure</div><div><br class=""></div><div>var m = NSMapTable<String, Data>(keyOptions: [.copyIn, .objectPersonality], valueOptions: [.weakMemory, .objectPersonality])<br class=""><br class="">var key = "hello"<br class="">var value = Data(bytes: [0, 1, 2, 3])<br class=""><br class="">m.setObject(value, forKey: key) // after here there are no more references to value so it is destroyed<br class=""><br class="">assert(m.object(forKey: key) != nil) // this now fails</div><div><br class=""></div><div>In that second example even if you had a usage of value past the setObject method call that was a mutation it would also fail the assert because the backing reference would have changed.</div><div><br class=""></div><div>I guess what I am saying is there are edge cases that we have to be careful with.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><div class=""><br class=""></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class="">3) Since Foundation is likely the most impact here I think it would be useful to audit the results of this before pushing it out; specifically the Foundation internal builds so that we can make sure the things we are working on function correctly.</div><div class=""><br class=""></div><div class="">Do you have implementations in the works yet? I really think this is important for us to get in (especially before the ABI gets locked down cause it could have impact there…)</div></div></div></blockquote><br class=""></div><div class=""><br class=""></div>No I don’t, but would be open to digging into it and seeing what I could do as a proof-of-concept (I just don’t know where I’d start looking to accomplish this).</div></div></blockquote></div><br class=""><div class=""><br class=""></div><div class="">Dont get me wrong; I think this is a great idea and vastly improves the state of affairs – imho it is very well worth doing and getting this done before we cannot change it.</div></body></html>