[swift-evolution to bcc]

Hi, Andrew. Objective-C exceptions are not the same as Swift errors (the things 
that are thrown); they have effectively come to indicate fatal conditions in 
Apple’s frameworks, and neither Objective-C nor Swift are compiled 
exception-safe in the C++ sense.* (That is, if an Objective-C exception is 
raised, the program will leak, and some objects may be in an invalid state.)

Swift errors correspond to the Cocoa NSError idiom, and the latter is imported 
as such.

Separately, issues with Cocoa APIs should be filed as bug reports with Apple, 
rather than raised on the swift.org mailing lists or bug tracker. The Swift 
Open Source project does not control Apple’s APIs, and the features which do 
affect particular frameworks (the SDK “overlays” and “API notes”) come from the 
particular framework teams within Apple.

Best,
Jordan

* Objective-C can be compiled in an exception-safe mode, but it’s off by 
default. I don’t know if Apple’s frameworks are compiled in this mode.


> On Jul 11, 2016, at 20:07, Andrew Tetlaw via swift-evolution 
> <[email protected]> wrote:
> 
> Apologies if this has been discussed, I couldn't find any mention in the list 
> or on https://github.com/apple/swift-3-api-guidelines-review 
> <https://github.com/apple/swift-3-api-guidelines-review>.
> 
> The NSIncrementalStore method:
> 
>     func referenceObjectForObjectID(_ objectID: NSManagedObjectID) -> 
> AnyObject
> 
> Can thrown an exception, but it's not marked as throws. From the 
> documentation:
> 
> "This method raises an NSInvalidArgumentException if the object ID was not 
> created by the receiving store."
> 
> NSExpression has a constantValue property:
> 
>     var constantValue: AnyObject { get }
> 
> that can raise an exception at runtime, but it's not marked as throws. From 
> the documentation:
> 
> 'Accessing this property raises an exception if it is not applicable to the 
> expression."
> 
> The NSExpression constantValue property can also return nil at runtime, but 
> it's return type is AnyObject; not an optional.
> 
> If you construct an NSComparisonPredicate with a format string like:
> 
>     "property == nil"
> 
> and you examine the expression returned by predicate.rightExpression. You 
> can't call expression.constantValue from Swift because it'll crash with 
> EXC_BAD_ACCESS. You also can't protect against a nil value because the return 
> type is not optional.
> 
> 
> To protect Swift against both of these situations, you have to use 
> Objective-C wrapper functions. For example to protect against exceptions:
> 
> NSException *_Nullable IADCatchObjCException(void (^_Nullable block)())
> {
>     NSException *exception = nil;
>     @try {
>         if (block) {
>             block();
>         }
>     } @catch (NSException *e) {
>         exception = e;
>     }
>     return exception;
> }
> 
> To protect against a surprise nil at runtime:
> 
> inline _Nullable id IADMaybeNilValue(_Nullable id value)
> {
>     return value ?: nil;
> }
> 
> I was hoping this could be improved for the Swift API?
> 
> --
> Andrew Tetlaw
> _______________________________________________
> swift-evolution mailing list
> [email protected]
> https://lists.swift.org/mailman/listinfo/swift-evolution

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to