gpt4 book ai didi

协议(protocol)的 Swift 扩展存储

转载 作者:IT王子 更新时间:2023-10-29 05:43:24 24 4
gpt4 key购买 nike

我制定了一个协议(protocol):

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)来定义属性:

protocol SomeProtocolInjectable {
var source: SomeProtocol! { get set }
}

现在我只需要用这个属性扩展 View Controller :

extension UIViewController: SomeProtocolInjectable {
// ???
}

我如何破解一个可与协议(protocol)类型一起使用的存储属性?

什么没用:

还有什么建议吗?

最佳答案

任何协议(protocol)对象都可以转换为类型删除类。构建一个 AnySomeProtocol 并存储它。

private var sourceKey: UInt8 = 0

final class AnySomeProtocol: SomeProtocol {
func getData() -> String { return _getData() }
init(_ someProtocol: SomeProtocol) { _getData = someProtocol.getData }
private let _getData: () -> String
}

extension UIViewController: SomeProtocolInjectable {
var source: SomeProtocol! {
get {
return objc_getAssociatedObject(self, &sourceKey) as? SomeProtocol
}
set(newValue) {
objc_setAssociatedObject(self, &sourceKey, AnySomeProtocol(newValue), .OBJC_ASSOCIATION_RETAIN)
}
}
}

class MyViewController : UIViewController {
override func viewDidLoad() {
self.title = source.getData()
}
}

调用者只能使用它来访问协议(protocol)方法。您不能使用 as 将其强制恢复为原始类型,但无论如何您都应该避免这种情况。

作为旁注,我真的建议让 source 返回 SomeProtocol? 而不是 SomeProtocol!。这里没有任何内容可以保证 source 将被设置。在 viewDidLoad 之前,您甚至不需要设置它。

关于协议(protocol)的 Swift 扩展存储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34933928/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com