我正在运行带有objc和swift的大量旧代码的项目。
我一直在使用objc MPOldKeychainManager
,现在不赞成使用它,而将使用swift的NewKeychainManager
。
问题如下:MPOldKeychainManager
编写了一些类别,但我不想将它们重写为快速扩展。
我所做的是:
NewKeychainManager
(在“ myTarget-Swift.h
”中可见)派生的类命名为“ MPOldKeychainManager
” MPOldKeychainManager
的objc声明...希望类别仍然有效。
objc(MPOldKeychainManager)
class NewKeychainManager: KeychainManager {
}
不幸的是,即使我已将导入的标头更新为MPOldKeychainManager
myTarget-Swift.h
(从swift派生)
#import "myTarget-Swift.h" //previously - objc "MPOldKeychainManager.h"
@interface MPOldKeychainManager (Authentication)
问题:是否可以对从swift派生的objc类使用类别?
答案 0 :(得分:1)
如果您还没有看到它,这里是一个有用的资源,可用于从Objective-C迁移到Swift:https://developer.apple.com/documentation/swift/migrating_your_objective_c_code_to_swift。除其他外,它指出不能在Objective-C中继承Swift类。您要尝试做的是为MPOldKeychainManager
Swift类指定一个不同的Objective-C名称NewKeychainManager
。
实际上,如果您在objc
之前添加一个&号,则可以正常工作,就像这样:
@objc(MPOldKeychainManager)
class NewKeychainManager: KeychainManager {
}
然后可以在Objective-C中使用所有现有的类别。但是,在Swift中使用它们会遇到问题,因为要在Swift中使用它们,它们必须在桥接标头中可用,并且您将无法使用类的Objective-C名称({{1} })。
但是,您可以编写一个Objective-C包装器类,该类将具有与每个类别方法相对应的方法,并且还采用MPOldKeychainManager
指针。然后,包装方法可以委托给Objective-C代码可用的category方法,因此您不必在Swift中重新实现category方法。
比方说,Objective-C类别具有方法NewKeychainManager
:
authenticateUser:
该方法可以包装如下:
@interface MPOldKeychainManager (Authentication)
-(void)authenticateUser:(int32_t)uid;
@end
此接口声明必须可通过桥接头直接或间接使用。然后,可以在您的Objective-C代码中的某个地方实现包装器,如下所示:
@interface OldKCMWrapper : NSObject
+(void)authenticateUser:(int32_t)uid withManager:(NewKeychainManager*)inst;
@end
然后可以在Swift代码中使用包装器,例如:
@implementation OldKCMWrapper
+(void)authenticateUser:(int32_t)uid withManager:(MPOldKeychainManager*)inst {
[inst authenticateUser:uid];
}
@end
实际上,包装器可以在let kcm = NewKeychainManager()
OldKCMWrapper.authenticateUser(321, with: kcm)
的Swift扩展中使用。您仍将拥有一个Swift扩展,并具有与所有Objective-C类别方法等效的功能,但是您不必在Swift中重新实现它们的代码:扩展中的方法将简单地委派给包装器。
希望这会有所帮助。还有其他实现此想法的方法,可能更优雅。