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 }
    }
}