NS_REFINED_FOR_SWIFT and return value

拟墨画扇 提交于 2019-12-18 09:22:39

问题


I'm new with Swift and I begin exploring some feature for bridging with Objective-C.

Currently I have a method with NSError reference which is:

- (BOOL) verifyPersonalizationWithError:(NSError **) error NS_REFINED_FOR_SWIFT;

Now I can access the method in Swift for some refinements, but the return value is lost. The generated method for Swift is:

open func __verifyPersonalization() throws

The error is correctly handled with the do catch but the return value seems to be lost.

Any missing thing for my NS_REFINED_FOR_SWIFT macro?


回答1:


This is unrelated to the NS_REFINED_FOR_SWIFT macro. The Objective-C method

 - (BOOL) verifyPersonalizationWithError:(NSError **) error;

is imported to Swift as

open func verifyPersonalization() throws

and the only effect of the NS_REFINED_FOR_SWIFT macro is to prepend underscores to the Swift method name

open func __verifyPersonalization() throws

which allows to provide a refined Swift interface in an extension, while keeping the original implementation available to be called from the refined interface (see "Refining Objective-C Declarations" in Swift and Objective-C in the Same Project).

The Swift importer assumes that the boolean return value of the Objective-C method indicates success or failure, which is the common Cocoa pattern as documented in Using and Creating Error Objects:

Important: Success or failure is indicated by the return value of the method. Although Cocoa methods that indirectly return error objects in the Cocoa error domain are guaranteed to return such objects if the method indicates failure by directly returning nil or NO, you should always check that the return value is nil or NO before attempting to do anything with the NSError object.

A typical usage in Objective-C is

NSError *error;
if ([self verifyPersonalizationWithError:&error]) {
    NSLog(@"success");
} else {
    NSLog(@"failed: %@", error.localizedDescription);
}

The Swift method throws an error on failure, so there is no need for a boolean return value:

do {
    try verifyPersonalization()
    print("success")
} catch {
    print("failed:", error.localizedDescription)
}

If the Objective-C method really indicates failure by leaving a non-null error in the error parameter (instead of returning false, which is the usual Cocoa pattern) then you can indicate that by adding a attribute:

- (BOOL) verifyPersonalizationWithError:(NSError **) error
    __attribute__((swift_error(nonnull_error)));

which is imported to Swift as

open func verifyPersonalization() throws -> Bool

The swift_error attribute is documented at https://github.com/apple/swift-clang/blob/383859a9c4b964af3d127b5cc8abd0a8f11dd164/include/clang/Basic/AttrDocs.td#L1800-L1819



来源:https://stackoverflow.com/questions/45565960/ns-refined-for-swift-and-return-value

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!