简体   繁体   English

Swift类指针为? 类协议?

[英]Swift Class Pointer as? Class Protocol?

I have a class, lets call it SomeClass. 我有一堂课,叫它SomeClass。 Instances of SomeClass have an optional pointer to SomeOtherClass. SomeClass的实例具有指向SomeOtherClass的可选指针。 In this way, instances of SomeClass can be instantiated, given a pointer to SomeOtherClass (or a subclass of SomeOtherClass), and then this pointer can be used to dynamically create instances of this SomeOtherClass belonging to SomeClass. 通过这种方式,可以实例化SomeClass的实例,并提供指向SomeOtherClass(或SomeOtherClass的子类)的指针,然后可以使用该指针动态创建属于SomeClass的SomeOtherClass的实例。 Eg; 例如;

class SomeClass {
    var classPointer: SomeOtherClass.Type?
}

class SomeOtherClass {
}

So far so good. 到现在为止还挺好。 Now, I have a protocol - lets call it SomeProtocol - that I want SomeOtherClass to conform to. 现在,我有了一个协议-让我们称之为SomeProtocol-我希望SomeOtherClass遵守该协议。 This protocol has class functions in it: 该协议具有类功能:

protocol SomeProtocol {
    static func someClassFunction()
}

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

As expected, I can then call this protocol class function on SomeOtherClass like so: 如预期的那样,然后可以在SomeOtherClass上调用此协议类函数,如下所示:

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

Here is the troublesome part. 这是麻烦的部分。 I want to dynamically determine if an instance of SomeClass' classPointer conforms to SomeProtocol, and if so execute the class function on it. 我想动态确定SomeClass的classPointer的实例是否符合SomeProtocol,如果是,则对它执行类函数。 So, I try to cast the pointer using as?: 因此,我尝试使用as强制转换指针:

// 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"
}

And the build fails with the error "Static member of someClassFunction cannot be used on instance of type SomeProtocol". 并且构建失败,并显示错误“无法在SomeProtocol类型的实例上使用someClassFunction的静态成员”。

Is there a way to accomplish what I'm attempting? 有什么方法可以完成我的尝试? Currently if this doesn't work I can only think of these alternatives (none are preferable and they're all rather hacky): 目前,如果这行不通,我只能想到这些替代方法(没有其他方法是可取的,它们都相当笨拙):

  1. Switch to objective c. 切换至目标c。
  2. Switch the protocol to use instance functions instead, then instantiate a temporary instance of SomeClass' classPointer and message it with any necessary functions, then release the instance. 将协议切换为使用实例函数,然后实例化SomeClass的classPointer的临时实例,并使用任何必要的函数向其发送消息,然后释放该实例。

For completeness, here is all of the code together that can be pasted into a Playground (it won't build due to the error I mentioned though): 为了完整起见,这是可以粘贴到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"
}

Thanks for any help you can provide, - Adam 感谢您提供的任何帮助-亚当

Ahah! 啊啊! As usual, as soon as I make the SO post, I figure out the answer. 像往常一样,一旦我发表SO帖子,我便会找到答案。

For those wondering, you must cast the classPointer as the protocol's Type, not as the protocol itself. 对于那些好奇的人,必须将classPointer强制转换为协议的Type,而不是协议本身。 The line: 该行:

if let conformingClass = someInstance.classPointer as? SomeProtocol {

Needs to be changed to: 需要更改为:

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

And you'll then be able to message conformingClass with the class functions declared in SomeProtocol. 然后,您将能够使用SomeProtocol中声明的类函数向conformingClass发送消息。 The complete working code is: 完整的工作代码为:

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()
}

And it works :). 它有效:)。

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

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