ObjC generic containers and ObjectiveCBridgeable conformance


(Joe Groff) #1

Importing ObjC generics is currently disabled for the bridged container classes, NSArray, NSDictionary, and NSSet. To enable generics for these types, we need to figure out what to do about their interaction with ObjectiveCBridgeable container bridging. The mapping from generic Swift value type to generic ObjC class is nontrivial, since the element type may itself be bridged—Array<String> bridges to NSArray<NSString>, whereas Array<NSFileHandle> would bridge to NSArray<NSFileHandle>. We'd need multiple constrained conformances to be able to accurately model this relationship at compile time. Absent that functionality, I can think of a couple of approaches in the short term:

1) Do nothing, and import NSArray and friends as nongeneric types.
2) Import NSArray and friends as generic, and define the ObjectiveCBridgeable relationship in terms of their upper bound type, so that Array<T> bridges to NSArray<AnyObject>, Dictionary<T,U> to NSDictionary<NSCopying, AnyObject>, and so on.
3) Do (2), but also do additional special-case bridging in the compiler (again), to insert unchecked conversions from the upper bound types like NSArray<AnyObject> to the appropriate generic type NSArray<T>.

Are there any other approaches I'm missing?

-Joe


(Douglas Gregor) #2

Importing ObjC generics is currently disabled for the bridged container classes, NSArray, NSDictionary, and NSSet. To enable generics for these types, we need to figure out what to do about their interaction with ObjectiveCBridgeable container bridging. The mapping from generic Swift value type to generic ObjC class is nontrivial, since the element type may itself be bridged—Array<String> bridges to NSArray<NSString>, whereas Array<NSFileHandle> would bridge to NSArray<NSFileHandle>. We'd need multiple constrained conformances to be able to accurately model this relationship at compile time. Absent that functionality, I can think of a couple of approaches in the short term:

1) Do nothing, and import NSArray and friends as nongeneric types.
2) Import NSArray and friends as generic, and define the ObjectiveCBridgeable relationship in terms of their upper bound type, so that Array<T> bridges to NSArray<AnyObject>, Dictionary<T,U> to NSDictionary<NSCopying, AnyObject>, and so on.
3) Do (2), but also do additional special-case bridging in the compiler (again), to insert unchecked conversions from the upper bound types like NSArray<AnyObject> to the appropriate generic type NSArray<T>.

I had (3) in mind.

However, the value of having generic NSArray/NSSet/NSDictionary in Swift is outweighed by the implementation cost of doing tis, especially because it is very likely we will never be able to accurately model the relationship at compile time.

Are there any other approaches I'm missing?

I can’t think of any other approaches.

  - Doug

···

On Apr 27, 2016, at 10:23 AM, Joe Groff <jgroff@apple.com> wrote: