从Swift中的非泛型函数调用泛型函数

时间:2015-10-24 03:41:22

标签: objective-c swift generics interop

MMCondition是Swift中定义的协议,但与Objective-C(使用@objc注释)互操作。

@objc public protocol MMCondition {
    static var name: String { get }
    static var isMutuallyExclusive: Bool { get }
}

我有以下代码:

// addCondition cannot be generic as I want it to be accessible from Objective-C as well.
public func addCondition(condition: MMCondition) {
    // How do I initialize OperationConditionImplementer here?
   let operationCondition = OperationConditionImplementer(condition: condition) // doesn't compile
   // Error: Cannot invoke initializer for type 'OperationConditionImplementer<T>' with an argument list of type '(condition: MMCondition)'
   // Can I use condition.dynamicType to init OperationConditionImplementer somehow?
}

struct OperationConditionImplementer<T: MMCondition> {
    let condition: T

    static var name: String {
        return "Silent<\(T.name)>"
    }

    static var isMutuallyExclusive: Bool {
        return T.isMutuallyExclusive
    }

    init(condition: T) {
        self.condition = condition
    }
}

2 个答案:

答案 0 :(得分:2)

从Objective-C,您不能使用documentation中所述的泛型。

  

您可以访问类或协议中的任何内容   标有@objc属性,只要它兼容   Objective-C的。这不包括仅限Swift的功能,例如列出的功能   这里:

     
      
  • 泛型
  •   
     

...

因此您需要完全删除泛型代码。一种可能的解决方案可能是:

@objc protocol MMCondition {
    static var name: String { get }
    static var isMutuallyExclusive: Bool { get }
}

struct OperationConditionImplementer {
    let condition: MMCondition

    var name: String {
        return "Silent<\(condition.dynamicType.name)>"
    }

    var isMutuallyExclusive: Bool {
        return condition.dynamicType.isMutuallyExclusive
    }

    init(condition: MMCondition) {
        self.condition = condition

        // Here decide comparing types
        if condition.dynamicType === ExampleCondition.self {
            print(condition.dynamicType.name)
        }
    }
}

例如,如果你在游乐场试试:

class ExampleCondition: NSObject, MMCondition {
    static var name: String  = "ExampleCondition"
    static var isMutuallyExclusive: Bool = false
}

let example = OperationConditionImplementer(condition: ExampleCondition())

您将看到“ExampleCondition”已打印。

如果您最终切换到纯Swift,则需要在初始化T时指定OperationConditionImplementer

您可以将addCondition方法定义为:

func addCondition<T: MMCondition>(condition: T) {
   let a = OperationConditionImplementer<T>(condition: condition)
}

答案 1 :(得分:2)

由于通用的Swift 2.0实例可以实现Objective-C协议。什么不可能我相信有一个结构实现协议。事实上,我希望您的协议可能需要继承NSObjectProtocol才能在Objective-C中使用,这会阻止您使用结构或枚举来实现协议。

您还正确地提到您无法从Objective-C访问泛型函数。

有关使用泛型来实现Objective-C协议的具体示例,请查看this blog post