[swift-evolution] Mutability for Foundation types in Swift

Douglas Gregor dgregor at apple.com
Mon Apr 25 12:32:12 CDT 2016


> On Apr 25, 2016, at 9:20 AM, Tony Parker via swift-evolution <swift-evolution at swift.org> wrote:
> 
> Hi Brent,
> 
> Thanks for your feedback! You’ve got some great questions below, I’ll try to answer them as best I can.
> 
>> On Apr 24, 2016, at 3:44 AM, Brent Royal-Gordon <brent at architechies.com> wrote:
>> 
>>> We took this feedback seriously, and I would like to share with you the start of an important journey for some of the most commonly used APIs on all of our platforms: adopting value semantics for key Foundation types.
>> 
>> This proposal is way cool, and I think you've selected a great starting set of APIs.
>> 
>> Of the other candidate APIs you mentioned, I'm definitely looking forward to AttributedString and some parts of the NSURL Loading system (primarily the requests and responses; the connections and sessions should probably be object types). Predicate, OrderedSet, CountedSet, and possibly Number and Value make sense as well.
>> 
>> However, I think that Locale, Progress, Operation, Calendar, and Port are poor candidates for becoming value types, because they represent specific resources which may be partially outside of your thread's/process's control; that is, they're rather like NS/UIView, in that they represent a specific, identifiable "thing" which cannot be copied without losing some aspect of its meaning.
> 
>>>   if !isUniquelyReferencedNonObjC(&_box) {
>> 
>> 
>> Something I have often wondered about: Why doesn't `isUniquelyReferenced(_:)` use `-retainCount` on Objective-C objects? Alternatively, why not use `-retainCount` on fields in your value types when you're trying to implement COW behavior? It seems like that would allow you to extend the copy-on-write mechanism to Objective-C objects. I know that `-retainCount` is usually not very useful, but surely this copy-on-write situation, where you are using it in an advisory fashion and an overestimated retain count will simply cause you to unnecessarily lose some efficiency, is the exception to the rule?
>> 
>> There are likely good reasons for this decision—they simply aren't obvious, and I'd like to understand them.
>> 
>> -- 
>> Brent Royal-Gordon
>> Architechies
>> 
> 
> There are a few reasons for this, but the one that sticks out most to me is that in Objective-C, retain, release, and retainCount don’t include weak references. If you take a look at the internals for the swift retain count function, you’ll see that there are two: owned and unowned.


Right. I went down this rabbit hole a few weeks ago, trying to determine if we could make an “isUniquelyReferenced” that works for Objective-C-defined classes. One obvious issue is that you can’t always trust retainCount to do the right thing for an arbitrary Objective-C class, because it may have been overridden. We can probably say “don’t do that” and get away with it, but that brings us to Tony’s point: Objective-C weak references are stored in a separate side table, so we can’t atomically determine whether an Objective-C class is uniquely referenced. On platforms that have a non-pointer “isa” we could make this work through the inline reference count (which requires changes to the Objective-C runtime and therefore wouldn’t support backward deployment), but that still doesn’t give us “isUniquelyReferenced” for Objective-C classes everywhere.

Interestingly, while Swift’s object layout gives us the ability to consider the weak reference count, the Swift runtime currently does not do so. IIRC, part of our reasoning was that isUniquelyReferencedNonObjC is generally there to implement copy-on-write, where weak references aren’t actually interesting. However, we weren’t comfortable enough in that logic to commit to excluding weak references from isUniquelyReferencedNonObjC “forever", and certainly aren’t comfortable enough in that reasoning to enshrine “excluding weak references” as part of the semantics of isUniquelyReference for Objective-C classes.

	- Doug

-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20160425/f7e462f0/attachment.html>


More information about the swift-evolution mailing list