我想写一个弱属性要求的协议.符合它的类必须能够为此属性指定任何类型.此外,我不想指定实际类型,因此它应该是使用某些协议指定的类型.此代码显示了我对非弱属性的想法:
protocol ObjectProtocol: class {
typealias PropertyType
var property: PropertyType {get set}
}
protocol FirstPropertyProtocol: class {}
protocol SecondPropertyProtocol: class {}
class FirstObjectImpl: ObjectProtocol {
var property: FirstPropertyProtocol?
}
class SecondObjectImpl: ObjectProtocol {
var property: SecondPropertyProtocol?
}
Run Code Online (Sandbox Code Playgroud)
它按预期工作.
我试图为弱属性做同样的事情:
protocol ObjectProtocol: class {
typealias WeakPropertyType: AnyObject //must be a class type
weak var weakProperty: WeakPropertyType? {get set}
}
protocol WeakPropertyProtocol: class {}
class ObjectImpl: ObjectProtocol {
weak var weakProperty: WeakPropertyProtocol?
}
Run Code Online (Sandbox Code Playgroud)
我收到了编译错误:
类型'ObjectImpl'不符合协议'ObjectProtocol'
有什么方法可以让我的工作吗?
我让它与 WeakPropertyProtocol 的 @objc 属性一起使用:
protocol ObjectProtocol: class {
typealias WeakPropertyType: AnyObject //must be a class type
weak var weakProperty: WeakPropertyType? {get set}
}
@objc protocol WeakPropertyProtocol {}
class SomeObjectImpl: ObjectProtocol {
weak var weakProperty: WeakPropertyProtocol?
}
Run Code Online (Sandbox Code Playgroud)
这不是最好的解决方案,因为我担心苹果文档的这条说明
另请注意,@objc 协议只能由继承自 Objective-C 类或其他 @objc 类的类采用。
我可以忍受这个限制,但如果有更好的解决方案,我将不胜感激。
作为与 Xcode 14.0 捆绑在一起的 Swift 5.7,编译器会发出错误:“'weak' 无法应用于协议中的属性声明”
可能的协议限制解决方法使用计算变量和由计算变量包装的补充“弱”变量。
解决方法 1:此解决方法不会强制应用协议的类型将属性设置为弱
protocol SharedInformation {
var name: UIViewController? { get set }
}
class Country: SharedInformation {
private weak var _name: UIViewController?
var name: UIViewController? {
get {
_name
}
set {
_name = newValue
}
}
}
Run Code Online (Sandbox Code Playgroud)
解决方法 2:此方法强制应用协议的类型使用弱存储包装属性。
protocol SharedInformation {
var name: Weak<UIViewController> { get set }
}
class Country: SharedInformation {
var name: Weak<UIViewController> = .init()
func usage() {
// set
name.wrappedValue = UIViewController()
// get
let value = name.wrappedValue
}
}
public struct Weak<Wrapped: AnyObject> {
public weak var wrappedValue: Wrapped?
public init(_ value: Wrapped? = nil) {
self.wrappedValue = value
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
4641 次 |
| 最近记录: |