Swift Class指针为?类协议?

时间:2016-03-08 15:18:05

标签: ios swift class casting protocols

我有一个类,我们称之为SomeClass。 SomeClass的实例有一个指向SomeOtherClass的可选指针。通过这种方式,可以实例化SomeClass的实例,给定指向SomeOtherClass(或SomeOtherClass的子类)的指针,然后此指针可用于动态创建属于SomeClass的此SomeOtherClass的实例。例如;

class SomeClass {
    var classPointer: SomeOtherClass.Type?
}

class SomeOtherClass {
}

到目前为止一切顺利。现在,我有一个协议 - 让我们称之为SomeProtocol - 我希望SomeOtherClass符合。该协议中包含类函数:

protocol SomeProtocol {
    static func someClassFunction()
}

extension SomeOtherClass : SomeProtocol {
    class func someClassFunction() {
        print("I am a class function being executed on SomeOtherClass")
    }
}

正如所料,我可以在SomeOtherClass上调用此协议类函数,如下所示:

SomeOtherClass.someClassFunction() // Prints "I am a class function being executed on SomeOtherClass"

这是麻烦的部分。我想动态确定SomeClass的classPointer的实例是否符合SomeProtocol,如果是,则执行类函数。所以,我尝试使用?:

来转换指针
// Create an instance of SomeClass and set it's classPointer to the SomeOtherClass class
let someInstance = SomeClass()
someInstance.classPointer = SomeOtherClass.self

// Check if the instance's classPointer class conforms to the SomeProtocol protocol
if let conformingClass = someInstance.classPointer as? SomeProtocol {
    // If so, execute the class function in SomeProtocol on the instance's classPointer
    conformingClass.someClassFunction() // Build fails "Static member someClassFunction cannot be used on instance of type SomeProtocol"
}

构建失败并出现错误“someClassFunction的静态成员不能在SomeProtocol类型的实例上使用”。

有没有办法完成我正在尝试的东西?目前,如果这不起作用,我只能想到这些替代方案(没有一个是优选的,而且它们都非常黑客):

  1. 切换到目标c。
  2. 将协议切换为使用实例函数,然后实例化SomeClass的classPointer的临时实例并使用任何必要的函数发送消息,然后释放实例。
  3. 为了完整性,以下是可以粘贴到Playground中的所有代码(由于我提到的错误,它不会构建):

    class SomeClass {
        var classPointer: SomeOtherClass.Type?
    }
    
    class SomeOtherClass {
    }
    
    protocol SomeProtocol {
        static func someClassFunction()
    }
    
    extension SomeOtherClass : SomeProtocol {
        class func someClassFunction() {
            print("I am a class function being executed on SomeOtherClass")
        }
    }
    
    // Create an instance of SomeClass and set it's classPointer to the SomeOtherClass class
    let someInstance = SomeClass()
    someInstance.classPointer = SomeOtherClass.self
    
    // Check if the instance's classPointer class conforms to the SomeProtocol protocol
    if let conformingClass = someInstance.classPointer as? SomeProtocol {
        // If so, execute the class function in SomeProtocol on the instance's classPointer
        conformingClass.someClassFunction() // Build fails "Static member someClassFunction cannot be used on instance of type SomeProtocol"
    }
    

    感谢您提供的任何帮助, - 亚当

1 个答案:

答案 0 :(得分:0)

AHAH!像往常一样,只要我发布SO帖子,我就会找到答案。

对于那些想知道的人,你必须将classPointer转换为协议的类型,而不是协议本身。这一行:

if let conformingClass = someInstance.classPointer as? SomeProtocol {

需要改为:

if let conformingClass = someInstance.classPointer as? SomeProtocol.Type {

然后您就可以使用SomeProtocol中声明的类函数向conformingClass发送消息。完整的工作代码是:

class SomeClass {
    var classPointer: SomeOtherClass.Type?
}

class SomeOtherClass {
}

protocol SomeProtocol {
    static func someClassFunction()
}

extension SomeOtherClass : SomeProtocol {
    class func someClassFunction() {
        print("I am a class function being executed on SomeOtherClass")
    }
}

// Create an instance of SomeClass and set it's classPointer to the SomeOtherClass class
let someInstance = SomeClass()
someInstance.classPointer = SomeOtherClass.self

// Check if the instance's classPointer class conforms to the SomeProtocol protocol
if let conformingClass = someInstance.classPointer as? SomeProtocol.Type {
    // If so, execute the class function in SomeProtocol on the instance's classPointer
    conformingClass.someClassFunction()
}

它有效:)。