如何要求协议只能由特定类采用


89

我想要这个协议:

protocol AddsMoreCommands {
     /* ... */
}

仅由从该类继承的类采用UIViewController该页面告诉我,我可以指定它仅由类(相对于结构)通过编写来采用

protocol AddsMoreCommands: class {
}

但是我看不到如何要求它仅由特定的班级采用。该页面稍后讨论将where子句添加到协议扩展中以检查一致性,但我也看不到如何对其进行调整。

extension AddsMoreCommands where /* what */ {
}

有没有办法做到这一点?谢谢!

Answers:


114
protocol AddsMoreCommands: class {
    // Code
}

extension AddsMoreCommands where Self: UIViewController {
    // Code
}

4
我差一点就收到了……我写的self不是Self:-(非常感谢,那很好!
emrys57 '16

对我来说,当我将其与强制转换结合使用时,这会引起一些语法上的奇怪。
克里斯·普林斯

3
如果您需要在协议中包含属性,则此方法将无效,因为扩展名不能包含存储的属性。
shim

1
它可以存储属性,您只需要使用此对象即可:objc_getAssociatedObject(self,&KeyName)as?属性类型
米哈尔Ziobro

这也需要在let / var声明具有类型时进行强制转换,AddsMoreCommands但是您传递给它的方法期望使用UIViewController
GoatInTheMachine

77

这也可以无需扩展即可实现:

protocol AddsMoreCommands: class where Self: UIViewController {
   // code
}

编辑2017/11/04:正如Zig指出的那样,这似乎在Xcode 9.1上生成警告。目前,在Swift项目(SR-6265)上报告了一个问题,以消除警告,我将密切注意并相应地更新答案。

EDITED 2018/09/29class如果将要存储实例的变量需要弱(例如委托),则需要此属性。如果您不需要弱变量,则可以省略class,只需编写以下内容,就不会发出任何警告:

protocol AddsMoreCommands where Self: UIViewController {
   // code
}

5
如何巧合的是,我点击了一个两岁的问题,并找到一个完美的解决方案张贴的一小时前😲
奥斯卡Apeland

Xcode 9.1现在向我发出这样的警告:冗余布局约束'Self':'AnyObject'。布局约束约束'Self':此处暗指'AnyObject'。将我的代码更改为可接受答案的格式似乎更好。
Zig

2
从Xcode 9.1开始,仅类协议现在使用AnyObject代替classprotocol AddsMoreCommands: AnyObject where Self: UIViewController { // code }
dodgio '17

@dodgio仍使用AnyObject
rgkobashi '17

1
@DávidPásztor是正确的,但是,如果要在委派等结构模式下使用它,则要使该属性变弱,必须明确添加“ class” :)
rgkobashi

48

由于前一个答案中的一个问题,我最终得到了以下声明:

protocol AddsMoreCommands where Self : UIViewController { 
    // protocol stuff here  
}

Xcode 9.1中没有警告


5
如果我错了,请纠正我,但是以上解决方案(在Xcode 9.1及更高版本中生成警告)的问题是,您不能将委托声明为弱者吗?
凯尔·戈斯兰

此外,当我用雨燕4.1这个解决方案,我需要的铸造性能AddsMoreCommands,以UIViewController我想这避免...
fl034

8
为了避免类型转换,您可以执行以下操作:typealias AddsMoreCommandsViewController = UIViewController & AddsMoreCommands
plu

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.