swift 弱引用数组

62 阅读1分钟
public struct Weak<T> {
    private weak var _value: AnyObject?

    public var value: T? {
        get {
            return _value as? T
        }
        set {
            _value = newValue.map { $0 as AnyObject }
        }
    }

    public init(value: T?) {
        self.value = value
    }
}

public struct WeakArray<Element> {
    private var array: [Weak<Element>] = []

    public var elements: [Element] {
        array.compactMap { $0.value }
    }

    public var weakReferenceCount: Int {
        array.count
    }

    public mutating func append(_ element: Element) {
        array = array.filter { $0.value != nil } + [Weak(value: element)]
    }

    public mutating func removeAll(where shouldDelete: (Element) throws -> Bool) rethrows {
        try array.removeAll { weakBox in
            guard let element = weakBox.value else { return true }
            return try shouldDelete(element)
        }
    }

    public mutating func cullExpired() {
        array.removeAll { weakBox in
            weakBox.value == nil
        }
    }
}

extension WeakArray: ExpressibleByArrayLiteral {
    public typealias ArrayLiteralElement = Element

    public init(arrayLiteral elements: Element...) {
        self.init()
        for element in elements {
            self.append(element)
        }
    }
}