【问题标题】:How to declare a swift class with a property that conforms to some protocol如何声明一个具有符合某些协议的属性的 swift 类
【发布时间】:2014-10-29 08:56:03
【问题描述】:

swift 是否有可能拥有一个从 xib 初始化的 ViewController 类,它的属性也是 UIViewController 的子类并符合某些协议?

    protocol SomeProtocol {
        // Some methods
    }

    class ViewController: UIViewController {
        // contentView is initialized from xib
        @IBOutlet weak var contentView: UIView!

        // I'd like to declare anotherViewController both conforms to 'SomeProtocol' 
        // and a subclass of UIViewController
        var anotherViewController: UIViewController!
        ...
    }  

当我将ViewController 声明为泛型类时,比如class ViewController<T: UIViewController, SomeProtocol>,我得到一个错误:

"Variable in a generic class cannot be presented in Objective-C"

如果我不能使用泛型类,我该如何实现呢?

【问题讨论】:

  • 尝试颠倒两者,即类 ViewController
  • @MatthiasBauch 我认为该链接不能解决我的问题。我想要一个UIViewController 属性,它符合某种协议,而不是符合某种协议并且可以分配UIViewController 的子类的属性。
  • @RajeevBhatia 它不起作用:(

标签: swift


【解决方案1】:

如果我误解了你的问题,请原谅我,但我认为你想要做的是声明一个继承自 UIViewController 并符合 SomeProtocol 的新类型,如下所示:

protocol SomeProtocol { }

class VCWithSomeProtocol: UIViewController, SomeProtocol {

}

class ViewController: UIViewController {
    var anotherViewController: VCWithSomeProtocol!
}

【讨论】:

  • 谢谢!它确实解决了我的问题。但是,我必须让我的许多视图控制器子类化为VCWithSomeProtocol,这不是我想要的。由于 Swift 不支持多重继承,我可能有自己的继承层次结构。
【解决方案2】:

所以我希望我也没有误解这个问题,但听起来你可能想要一个多继承对象级别的混合,例如:

let myVC: ViewController, SomeProtocol

不幸的是,Swift 不支持这一点。但是,有一个有点尴尬的解决方法可能会满足您的目的。

struct VCWithSomeProtocol {
    let protocol: SomeProtocol
    let viewController: UIViewController

    init<T: UIViewController>(vc: T) where T: SomeProtocol {
        self.protocol = vc
        self.viewController = vc
    }
}

然后,在任何你需要做 UIViewController 的任何事情的地方,你都可以访问结构的 .viewController 方面,而你需要协议方面的任何事情,你都可以引用 .protocol。

例如:

class SomeClass {
   let mySpecialViewController: VCWithSomeProtocol

   init<T: UIViewController>(injectedViewController: T) where T: SomeProtocol {
       self.mySpecialViewController = VCWithSomeProtocol(vc: injectedViewController)
   }
}

现在,当您需要 mySpecialViewController 执行任何与 UIViewController 相关的操作时,您只需引用 mySpecialViewController.viewController 并且当您需要它执行某些协议功能时,您可以引用 mySpecialViewController.protocol。

希望 Swift 4 将来允许我们声明一个带有附加协议的对象。但就目前而言,这是可行的。

希望这会有所帮助!

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-30
    相关资源
    最近更新 更多