Questions for bridging from OC to Swift


(old donkey) #1

Hi All:

Current bridging from Objective-C to Swift has this behaviour:

If we define a property in Objective-C, and we don’t say it is nullable or
nonnull, like this: @property (nonatomic, strong, readonly) NSString
*someString;

When we reference it from Swift, this property will be bridging to* String!*
(*implicitly unwrapped optional*) type automatically, and *there is no
warning indicate we should check if this is nil first.*

So the result is when some edge cases happen, the App will crash.

As more and more large projects are trying to use Swift now, this may seems
a problem for more people.

The documents I can find is: https://developer.apple.com/swift/blog/?id=25
and https://developer.apple.com/library/content/documentation/
Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html, it
says “Swift cannot distinguish between optional and nonoptional references,
and imports it as an implicitly unwrapped optional.”

As in Objective-C, the default property is nullable(if you don’t say it is
nonnull), I am curious what’s the reason that the property is not bridging
to optional, for me, feel optional value should be a better fit here.

Anyone know what’s the consideration at Swift 2 when this change happens?

Regards,
olddonkey


(Greg Parker) #2

Importing every unmarked Objective-C object pointer as strict optional makes traditional Objective-C interfaces cumbersome to use from Swift. You end up needing a nil check for every return value, every property access, etc. Such code is hard to read and hard to write.

Importing as implicitly-unwrapped optional is a usability compromise. Most Objective-C pointers are never actually nil. If a pointer is nil, and the author didn't check, then the process deliberately halts. This is no worse than the behavior you get when writing Objective-C code.

IUO import is intended to be a stopgap. In the long term every Objective-C interface ought to be explicitly annotated so that Swift can import them more precisely. In your own code you can use NS_ASSUME_NONNULL_BEGIN/END in your header files. Every un-annotated object pointer inside those markers is nonnull.

···

On May 30, 2017, at 12:11 PM, old donkey via swift-users <swift-users@swift.org> wrote:

Hi All:

Current bridging from Objective-C to Swift has this behaviour:

If we define a property in Objective-C, and we don’t say it is nullable or nonnull, like this: @property (nonatomic, strong, readonly) NSString *someString;

When we reference it from Swift, this property will be bridging to String! (implicitly unwrapped optional) type automatically, and there is no warning indicate we should check if this is nil first.

So the result is when some edge cases happen, the App will crash.

As more and more large projects are trying to use Swift now, this may seems a problem for more people.

The documents I can find is: https://developer.apple.com/swift/blog/?id=25 and https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/InteractingWithObjective-CAPIs.html, it says “Swift cannot distinguish between optional and nonoptional references, and imports it as an implicitly unwrapped optional.”

As in Objective-C, the default property is nullable(if you don’t say it is nonnull), I am curious what’s the reason that the property is not bridging to optional, for me, feel optional value should be a better fit here.

--
Greg Parker gparker@apple.com Runtime Wrangler