[swift-evolution] [Proposal draft] Bridge Optional As Its Payload Or NSNull

Douglas Gregor dgregor at apple.com
Thu Aug 25 11:34:54 CDT 2016


> On Aug 24, 2016, at 6:27 PM, Greg Parker <gparker at apple.com> wrote:
> 
> 
>> On Aug 23, 2016, at 3:36 PM, Douglas Gregor via swift-evolution <swift-evolution at swift.org <mailto:swift-evolution at swift.org>> wrote:
>> 
>> Proposed solution
>> 
>> When an Optional<T> value is bridged to an Objective-C object, if it contains some value, that value should be bridged; otherwise, NSNull or another sentinel object should be used.
>> 
> I don't think I like this.
> 
> Let me verify my understanding. If I have this:
> 
>     // imported from ObjC
>     func f(with object: Any)
>     
>     let s: String? = nil
>     f(s)
> 
> then at runtime it will call 
>     f([NSNull null])
> ?
> 
> The problem is that NSNull is in fact rare in Cocoa. They are used in the Foundation containers and almost nowhere else. Passing NSNull into almost any API is going to do something confusing at runtime. If you're lucky you get a prompt error "-[NSNull something]: unrecognized selector". If you're not lucky you'll get that error somewhere much later, or something even less obviously related to NSNull and your call site. That sounds like the wrong outcome for developers who are confused or careless or unaware of an optional.

I think there’s some confusion about what’s already in place due to SE-0116 <https://github.com/apple/swift-evolution/blob/master/proposals/0116-id-as-any.md> vs. what’s being proposed here. Specifically, your example:

>     // imported from ObjC
>     func f(with object: Any)
>     
>     let s: String? = nil
>     f(with:s)


Is accepted as part of SE-0116, because any Swift type can be placed in an Any, and anything can be bridged to Objective-C. Nearly all of the concerns in this thread are about this aspect of the already-accepted-and-implemented SE-0116: that an optional can get passed through to an Objective-C ‘id’ without being explicitly unwrapped. That behavior exists, and the type of the object seen in Objective-C is an opaque Swift wrapper type. I’d thought we were going to get some warnings when putting an optional into an Any that would end up going into Objective-C, but I don’t see the warning: maybe Joe can weigh in as to why we didn’t do that. 

*This* proposal is to make the object seen from Objective-C [NSNull null], so at least it’s predictable/detectable on the Objective-C side.

Now, for the related example:

	let s2: String? = “hello”
	f(with: s2)

Objective-C will see an NSString (well, Swift’s private subclass of NSString), rather than an opaque Swift wrapper type.

	- Doug


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


More information about the swift-evolution mailing list