简体   繁体   English

如何声明一个符合协议的特定类的属性?

[英]How to declare a property of a particular class which is also protocol conformant?

Suppose I want to create a property which is a subclass of UIViewController and also conformant to the protocol MyDelegateProtocol. 假设我想创建一个属性,它是UIViewController的子类,并且符合协议MyDelegateProtocol。 In Objective-C I would write something like: 在Objective-C中,我会写一些类似于:

@property (strong, nonatomic) UIViewController<MyDelegateProtocol> *delegate;

However, I'm not sure how to write this in Swift. 但是,我不知道如何在Swift中写这个。 I know how to declare a property which is protocol-conformant, or a property which is of a particular type: 我知道如何声明一个符合协议的属性,或者一个特定类型的属性:

let delegate : MyDelegateProtocol?
let delegate : UIViewController?

But I can't quite figure out how to make it do both. 但我无法弄清楚如何做到这两点。 If I try something like: 如果我尝试类似的东西:

let delegate : UIViewController<MyDelegateProtocol> ?

Then I get a compiler error about Cannot specialize non-generic type 'UIViewController' . 然后我得到一个编译器错误关于Cannot specialize non-generic type 'UIViewController' Probably because I'm wandering into the land of generics now. 可能是因为我现在正在徘徊在仿制药领域。 I've tried looking through the Swift book on protocols and other Stack Overflow questions regarding protocols, but I haven't found quite what I'm looking for. 我试过通过Swift关于协议的协议和其他Stack Overflow问题的书,但我还没有找到我正在寻找的东西。

First of all, I think this is a code smell. 首先,我认为这是代码味道。 If you want a delegate to be multiple things, there is most likely a separation of concerns problem. 如果您希望委托成为多个事物,则很可能存在关注点分离问题。

With that said, if you still want to do this, there isn't a way in Swift. 话虽如此,如果你仍然想要这样做,那么Swift就没有办法了。 You have a few options though: 你有几个选择:

  1. Add the required UIViewController methods to your delegate protocol ( my favorite option ) 将所需的UIViewController方法添加到委托协议( 我最喜欢的选项
  2. Create a superclass for your view controller that is a subclass of UIViewController and implements MyDelegateProtocol. 为您的视图控制器创建一个超类,它是UIViewController的子类并实现MyDelegateProtocol。 Declare your variable as that type 将变量声明为该类型
  3. Store two references to your "delegate". 存储两个对“委托”的引用。 One is of the MyDelegateProtocol and the other is of UIViewController 一个是MyDelegateProtocol,另一个是UIViewController
  4. Make your class generic, but this will not be accessible from Objective-C 使您的类具有通用性,但无法从Objective-C访问

3年后回答我自己的问题,Swift 4支持组合类和协议类型:

let delegate: UIViewController & MyDelegateProtocol

一年半之后回答我自己的问题,将未来的任何人都指向本文 ,它基本上回答了Swift 2中的问题。这不是严格可能的,但是使用协议扩展可以非常接近。

One option would be to parameterize your whole class; 一种选择是参数化整个班级; unfortunately, template classes can't be used from Obj-C. 遗憾的是,无法从Obj-C使用模板类。

class MyClass<Delegate: protocol<UIViewController, MyDelegateProtocol>> {
    ...
    let delegate: Delegate?
    ...
}

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

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