繁体   English   中英

如何在Swift中调用符合协议的泛型类型的静态方法

[英]How to call a static method of a generic type conforming to a protocol in Swift

说我有:

@objc public protocol InteractivelyNameable: Nameable {

    static func alertViewForNaming(_ existingObject: Nameable?,
                               context: NSManagedObjectContext,
                               completion:@escaping ((_ success: Bool, _ object: Nameable?, _ didCancel: Bool, _ error: Error?) -> Void)) -> UIAlertController?
}

我有一个通用的视图控制器,可以管理各种类型(通用类型是.fetchableObjectType ...基本上是NSManagedObject.self ..好,它的子类)。 我需要检查特定的对象类型是否符合协议,如果符合,请调用它。

就像是:

    // valid swift code
    if self.dataSource.fetchableObjectType is InteractivelyNameable {

        // not valid swift code
        if let alert = (self.dataSource.fetchableObjectType as! InteractivelyNameable).alertViewForNaming(....) { // ... do stuff }
    }

要将类型转换为“类级别”的协议,可以使用协议本身的.Type属性。

if let type = self.dataSource.fetchableObjectType as? InteractivelyNameable.Type {
   if let alert = type.alertViewForNaming(nil, context: self.dataSource.managedObjectContext, completion: completion) {

       // this code finds itself inside a UIViewController subclass...
       self.present(alert, animated: true, completion: nil)
          return
   }
}

通用形式的摘要:

    if let myConformingObject = someObject as? InteractivelyNameable {

        // invoke instance methods...
        myConformingObject.someInstanceMethodDefinedInProtocol()

        // invoke class methods
        type(of: myConformingObject).someClassMethodDefinedInProtocol()
    }

    // i.e. someTypeParameter = NSManagedObject.Type
    if let conformingType = someTypeParameter as? InteractivelyNameable.Type {
        conformingType.someClassMethodDefinedInProtocol()
    }

您编写的静态方法不是通用的,而是协议作为类型参数。 基本上,当您用作协议类型参数而不是通用形式时,可以强制编译器使用动态调度程序 ergo,Objective-C。

为了使用静态类型的分派器(Swift),您需要执行以下操作:

static func alertViewForNaming<T : Nameable>(_ existingObject: T,
                                         context: NSManagedObjectContext,
                                        completion:@escaping ((_ success: Bool, _ object: T, _ didCancel: Bool, _ error: Error?) -> Void)) -> UIAlertController?

这是一种通用类型约束方法,在这种情况下,它是协议类型约束AKA Nameable

您可以按以下方式调用静态方法:

let test : ObjectThatConformsToNameableProtocol = InteractivelyNameable.alertViewForNaming.....

这样,编译器可以为通用类型方法推断类型,在这种情况下为ObjectThatConformsToNameableProtocol

我没有测试代码,但是了解泛型和协议类型参数之间的区别很重要。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM