我正在使用 objc 和 swift 运行包含大量遗留代码的项目。
我一直在使用 objc MPOldKeychainManager
,现在已弃用,将使用 swift 的 NewKeychainManager
。
问题如下:MPOldKeychainManager
编写了一些类别,我不想将它们重写为快速扩展。
我所做的是:
- 将派生自
NewKeychainManager
的类命名为“MPOldKeychainManager
”(在“myTarget-Swift.h
”中可见) - 删除
MPOldKeychainManager
的 objc 声明
...希望这些类别仍然有效。
objc(MPOldKeychainManager)
class NewKeychainManager: KeychainManager {
}
不幸的是,旧扩展看不到 MPOldKeychainManager
(派生自 swift),即使我已将导入的 header 更新为 myTarget-Swift.h
#import "myTarget-Swift.h" //previously - objc "MPOldKeychainManager.h"
@interface MPOldKeychainManager (Authentication)
问题:是否可以对从 swift 派生的 objc 类使用类别?
- 我已经尝试过全新的命名
- 我已经尝试过大量干净构建
最佳答案
如果您还没有看到它,这里有一个从 Objective-C 迁移到 Swift 的有用资源:https://developer.apple.com/documentation/swift/migrating_your_objective_c_code_to_swift .其中,它声明不能在 Objective-C 中子类化 Swift 类。您要做的是为 NewKeychainManager
Swift 类指定一个不同的 Objective-C 名称 MPOldKeychainManager
。
实际上,如果您在 objc
之前添加一个符号,这将起作用,如下所示:
@objc(MPOldKeychainManager)
class NewKeychainManager: KeychainManager {
}
然后您可以在 Objective-C 中使用所有现有类别。但是,您将在 Swift 中使用它们时遇到问题,因为要在 Swift 中使用它们需要在桥接 header 中可用,并且您将无法使用类的 Objective-C 名称(MPOldKeychainManager
) 在桥接头中。
但是,您可以编写一个 Objective-C 包装类,该类将具有对应于每个类别方法的方法,并且还采用 NewKeychainManager
指针。然后,包装器方法可以委托(delegate)给 Objective-C 代码可用的类别方法,因此您不必在 Swift 中重新实现类别方法。
假设一个 Objective-C 类别有方法 authenticateUser:
:
@interface MPOldKeychainManager (Authentication)
-(void)authenticateUser:(int32_t)uid;
@end
该方法可以包装如下:
@interface OldKCMWrapper : NSObject
+(void)authenticateUser:(int32_t)uid withManager:(NewKeychainManager*)inst;
@end
此接口(interface)声明必须通过桥接 header 直接或间接可用。然后,在您的 Objective-C 代码中的某处,包装器可以这样实现:
@implementation OldKCMWrapper
+(void)authenticateUser:(int32_t)uid withManager:(MPOldKeychainManager*)inst {
[inst authenticateUser:uid];
}
@end
然后可以在 Swift 代码中使用包装器,例如:
let kcm = NewKeychainManager()
OldKCMWrapper.authenticateUser(321, with: kcm)
事实上,包装器可以用在 NewKeychainManager
的 Swift 扩展中。您仍然会有一个 Swift 扩展,其中包含所有 Objective-C 类别方法的等效项,但您不必在 Swift 中重新实现它们的代码:扩展中的方法将简单地委托(delegate)给包装器。
希望这对您有所帮助。还有其他方法可以实现这个想法,可能更优雅。
关于ios - 从 swift 派生的 obj-c 类的类别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51207323/