我制定了一个协议:
protocol SomeProtocol {
func getData() -> String
}
我创建一个符合它的结构:
struct SomeStruct: SomeProtocol {
func getData() -> String {
return "Hello"
}
}
现在我希望每个 UIViewController
都有一个名为 source
的属性,所以我可以做类似......
class MyViewController : UIViewController {
override func viewDidLoad() {
self.title = source.getData()
}
}
为此,我创建了一个协议来定义属性:
protocol SomeProtocolInjectable {
var source: SomeProtocol! { get set }
}
现在我只需要使用以下属性扩展视图控制器:
extension UIViewController: SomeProtocolInjectable {
// ???
}
如何将存储的属性与协议类型一起使用?
什么没用:
-
var source: SomeProtocol!
显然没有't work because extensions don' t存储了属性 -
我不能use Objective-C associated objects因为协议不是对象
-
我不能wrap it in a class(这适用于其他值类型,但不适用于协议)
还有其他建议吗?
3 回答
任何协议对象都可以转换为类型擦除类 . 构建一个
AnySomeProtocol
并存储它 .调用者只能使用它来访问协议方法 . 您无法使用
as
将其强制恢复为原始类型,但无论如何都应该避免这种情况 .作为旁注,我真的建议让
source
返回SomeProtocol?
而不是SomeProtocol!
. 这里没有任何承诺source
将被设定 . 你甚至没有设置它直到viewDidLoad
.你可以使用静态和视图控制器
hash
:如何为
getData()
添加一个默认实现,为协议提供一个虚拟结构实现,并将其用作source
变量的默认值:我冒昧地扩展
MyViewController
而不是UIViewController
,因为后者无论如何都不知道协议 .