ios - 从 swift 派生的 obj-c 类的类别

标签 ios objective-c swift

我正在使用 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/

相关文章:

ios - NSLayoutConstraints 未设置(swift 3)

ios - 在 Swift 中执行 Restkit addFetchRequestBlock 以删除孤儿

ios - 使用 dispatch_async,使用你自己的单独队列还是你自己的全局队列?

iOS:键盘问题背后的表格 View 隐藏部分

objective-c - 我的 OS X 应用不想打开它创建的文件

objective-c - 在 Xcode 中调试时智能 Obj-C 变量内容?

ios - swift 如何暂停音频

ios - 如何重叠 stackView 中的 subview ?

iphone - 如何在 iphone 应用程序中使用进度条

ios - UIGestureRecognizerStateEnded 的 Swift 等价物是什么?