在 Objective-C 中使用通用 Swift 类

Posted

技术标签:

【中文标题】在 Objective-C 中使用通用 Swift 类【英文标题】:Using a generic Swift class in Objective-C 【发布时间】:2015-09-04 21:57:29 【问题描述】:

假设我在 Swift 中定义了一个泛型类,类似于以下内容:

class MyArray<T> 
    func addObject(object: T) 
        // do something... hopefully
    

(我知道有一个稍微更好的数组实现,这只是一个例子。)

在 Swift 中,我现在可以非常轻松地使用这个类:

let a = MyArray<String>()
a.addObject("abc")

With Xcode 7, we now have generics in Objective-C,所以我假设我可以在 Objective-C 中使用这个类:

MyArray<NSString*> *a = [[MyArray<NSString*> alloc] init];
[a addObject:@"abc"];

但是,MyArray 从未添加到我的Project-Swift.h 文件中。即使我将其更改为从 NSObject 继承,它仍然不会出现在我的 Swift.h 文件中。

有没有办法创建一个通用的 Swift 类,然后在 Objective-C 中使用它?


更新:如果我尝试从 NSObject 继承并使用 @objc 进行注释:

@objc(MyArray)
class MyArray<T>: NSObject 
    func addObject(object: T) 
        // do something... hopefully
    

我收到以下编译器错误:

“@objc”类的通用子类不能有显式的“@objc”属性,因为它们在 Objective-C 中不直接可见。

这是否意味着没有办法在 Objective-C 中使用通用的 Swift 类?

如何直接引用类?

【问题讨论】:

你用@objc注释你的类了吗? @MrBeardsley 我刚试了一下,它给出了一个有趣的编译器错误(见上文)。 【参考方案1】:

Swift 泛型类型不能在 Objective-C 中使用。

https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/MixandMatch.html#//apple_ref/doc/uid/TP40014216-CH10-ID136

这不包括仅 Swift 的功能,例如此处列出的功能:

泛型 ...

【讨论】:

该文档是否针对 Xcode 7 进行了更新?既然现在 Objective-C 中已经有了泛型,那它不是被认为是 Swift 独有的特性吗? @Senseful:Objective-C 中的轻量级泛型与 Swift 泛型不同,而且限制更多。 @newacct 你知道描述限制的网页吗? Swift 2.2 的文档中删除了仅限 Swift 的排除列表。【参考方案2】:

当您需要将 Swift 泛型类导入到 Objective-C 时,有一种解决方法。

假设您有使用泛型的 Swift REST 服务。我正在使用Moya 框架,这就是我的服务的样子:

 class AuthService: BaseService<AuthAPI> 
    func register(email: String)  
       // ... 
    
 

它是从使用泛型的基础服务继承的,所以我不能直接在我的 Objective-C 代码中使用它。

所以这里有一个解决方法:

让我们创建AuthServiceProtocol:

@objc protocol AuthServiceProtocol 
    func register(email: String)

那么让我们为服务创建一个工厂(或者单例方法,没有区别):

@objc class Services: NSObject 
    static let authService: AuthServiceProtocol = AuthService()

然后我可以从 Objective-C 代码调用我的通用 Swift 身份验证服务:

- (void)someObjcMethod 
    [Services.authService registerWithEmail:self.email];

【讨论】:

我在我的 obj-c 类中成功调用了服务但是当我尝试使用 authService 时它给出了错误。 “在‘​​服务’类型的对象上找不到属性‘authService’。请帮我解决这个问题 一定要class AuthService: BaseService&lt;AuthAPI&gt;, AuthServiceProtocol吗? 如果 registerWithEmail 想要返回某种通用类怎么办 :)

以上是关于在 Objective-C 中使用通用 Swift 类的主要内容,如果未能解决你的问题,请参考以下文章

构建通用的 swift 框架

从 Swift 的 Objective-c 基础视图控制器继承

在objective-c中使用swift代码时的问题

在 Swift 中使用 Objective-C 扩展类

在 Objective-C 代码中使用 Swift 的缺点?

在 Objective-C 代码中使用 Swift 的缺点?