我在 Swift 3 中工作,采用在 Swift 2.3 Xcode 7 下构建和运行的类似应用程序的片段。我们正在开发具有一些相同功能的新应用程序。其中一些在外部库中。
在2.3项目中,我有一个文件:
#import <Foundation/Foundation.h>
#import <UIKit/UIImage.h>
@interface MMOCR : NSObject {
}
-(NSString*) doOCRAtImage:(UIImage*)scannedImage;
@end
该文件包含在桥接头文件中,它会编译并运行。这是代码:
let mmocr = MMOCR()
result = mmocr.doOCRAtImage(croppedImage)
但是在我的新项目中,我得到了这个:
“doOCRAtImage”已重命名为“do(at:)”
所以它识别类,但不识别方法。这是从 2.3 到 3 的变化吗?我还没有转换和编译旧项目,所以我不知道这个是否可以在 3 和 Xcode 8 下编译。
最佳答案
它确实识别您的方法,但它应用的是 Swift 3 的新命名约定。因此,当您调用此 Objective-C 方法时,您只需遵循该错误消息的指导并将其调用为 do(at:)
:
result = mmocr.do(at: croppedImage)
有关详细信息,请参阅 SE-0005: Better Translation of Objective-C APIs Into Swift或 WWDC 2016 视频 Swift API Design Guidelines .
顺便说一句,如果您可以编辑 @interface
(即如果 MMOCR
是您自己的类),您可以使用 NS_SWIFT_NAME< 覆盖 Swift 名称
:
- (NSString*) doOCRAtImage:(UIImage *)scannedImage NS_SWIFT_NAME(doOCR(at:));
然后,你会做:
let result = mmocr.doOCR(at: croppedImage)
就个人而言,如果 MMOCR
是您自己的类(class),我可能会想将 doOCRAtImage:
完全重命名为:
- (NSString*) recognizeTextInImage:(UIImage *)scannedImage;
那么,Swift 3 代码将是:
result = mmocr.recognizeText(in: croppedImage)
这是一个比仅使用 NS_SWIFT_NAME
更显着的变化,但它可能会在 Objective-C 和 Swift 3 中产生更直观的代码。
如果此 MMOCR
是您无法轻松修改的第三方库,您始终可以定义自己的扩展来为该方法提供一个替代的、更合乎逻辑的名称,例如:
extension MMOCR {
func recognizeText(in image: UIImage) -> String {
return self.do(at: image)
}
}
然后你可以这样做:
result = mmocr.recognizeText(in: croppedImage)
显然,您可以随意选择您想要的任何名称。但是通过这种方式,您可以在整个代码中使用这个更符合逻辑的名称,而不是神秘的 do(at:)
语法。
就我个人而言,我会向此 MMOCR
类的提供者提交增强请求,要求他们提供更合乎逻辑的 Swift 3 接口(interface)(使用 NS_SWIFT_NAME
或通过重命名方法),但扩展是一种与他们的 API 拥有优雅接口(interface)的方法,直到他们自己重新访问它为止。
关于Swift 无法识别来自 Obj-C 类的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40600640/