Arrays 弱保持元素的Swift数组
我从中得到了一些灵感 我希望能够维护一个数组,该数组包含对其元素的弱引用,以便在代码库中的其他地方发布这些元素时,我不会将它们保留在数组中 我希望实现尽可能的类型安全,但是应该是可重用的 我使用的策略是声明一个弱引用容器Arrays 弱保持元素的Swift数组,arrays,swift,generics,memory,weak-references,Arrays,Swift,Generics,Memory,Weak References,我从中得到了一些灵感 我希望能够维护一个数组,该数组包含对其元素的弱引用,以便在代码库中的其他地方发布这些元素时,我不会将它们保留在数组中 我希望实现尽可能的类型安全,但是应该是可重用的 我使用的策略是声明一个弱引用容器 class WeakRefContainer<T> where T: AnyObject { private(set) weak var value: T? init(value: T?) { self.value = value
class WeakRefContainer<T> where T: AnyObject {
private(set) weak var value: T?
init(value: T?) {
self.value = value
}
}
我试着按如下方式使用一切:
var weakReferencesArray = [WeakRefContainer<SampleClass>]()
let obj1 = WeakRefContainer.init(value: SampleClass())
let obj2 = WeakRefContainer.init(value: SampleClass())
weakReferencesArray.append(obj1)
weakReferencesArray.append(obj2)
weakReferencesArray.compact()
var weakReferencesArray=[WeakRefContainer]()
设obj1=WeakRefContainer.init(值:SampleClass())
让obj2=WeakRefContainer.init(值:SampleClass())
WeakReferenceArray.append(obj1)
WeakReferenceArray.append(obj2)
weakReferencesArray.compact()
当我尝试调用compact时,收到以下错误消息:
MyPlayground.playground:29:21: 'WeakRefContainer<SampleClass>' is not a subtype of 'WeakRefContainer<AnyObject>'
MyPlayerly.Playerly:29:21:“WeakRefContainer”不是“WeakRefContainer”的子类型
有人能帮我解锁吗?谢谢您的代码无法工作,因为
WeakRefContainer
不是WeakRefContainer
的子类,因为泛型在Swift中是不变的。因此,weakreferencearray
无法使用从扩展添加的compact
方法
通过协议,有一个解决方案:
protocol WeakHolder {
var hasRef: Bool { get }
}
extension WeakRefContainer: WeakHolder {
var hasRef: Bool { return value != nil }
}
extension Array where Element: WeakHolder {
func compacted() -> [Element] {
return filter { $0.hasRef }
}
mutating func compact() {
self = compacted()
}
}
我还将
compact
重命名为compressed
,以获得更好的快速语义,并将原始compact
替换为一个变异版本。您可能希望扩展应用于所有[WeakRefContainer]
其中T
可以是扩展任何对象的任何类型
extension Array where Element: WeakRefContainer<T> {
您应该将您的WeakRefContainer
设置为一个结构。我会避免在Array
上使用方法名compact()
,因为如果将compactMap
的标识映射版本添加到stdlib中,那么它很可能会被命名。另一个选项是扩展数组{func compact()->[Element]where Element==WeakRefContainer{
:)@Hamish噢,我不知道你可以这样约束Element
!谢谢!
protocol WeakHolder {
var hasRef: Bool { get }
}
extension WeakRefContainer: WeakHolder {
var hasRef: Bool { return value != nil }
}
extension Array where Element: WeakHolder {
func compacted() -> [Element] {
return filter { $0.hasRef }
}
mutating func compact() {
self = compacted()
}
}
extension Array where Element: WeakRefContainer<T> {
extension Array{
func compact<T>() -> [Element] where Element == WeakRefContainer<T> {
return filter { $0.value != nil }
}
}