WeakBox要求WeakArray <element> .Element为类类型

时间:2019-01-16 16:24:40

标签: swift

我正在尝试从objc对话(https://www.objc.io/blog/2017/12/28/weak-arrays/)实现存储弱引用解决方案,但是我无法使其工作。

确切的错误消息告诉您:

'WeakBox' requires that 'WeakArray<Element>.Element' (aka 'Optional<Element>') be a class type

enter image description here

使用以下代码:

final class WeakBox<A: AnyObject> {
    weak var unbox: A?

    init(_ value: A) {
        unbox = value
    }
}

struct WeakArray<Element: AnyObject> {
    private var items: [WeakBox<Element>] = []

    init(_ elements: [Element]) {
        items = elements.map { WeakBox($0) }
    }

    init() {}
}

extension WeakArray: Collection {
    var startIndex: Int { return items.startIndex }
    var endIndex: Int { return items.endIndex }

    subscript(_ index: Int) -> Element? {
        return items[index].unbox
    }

    func index(after idx: Int) -> Int {
        return items.index(after: idx)
    }

    mutating func append(_ element: Element) {
        items.append(WeakBox(element))
    }

    mutating func removeAll() {
        items.removeAll()
    }
}

**

更新:

**

一段时间后,我意识到错误消息是完全误导的。真正的问题在于 Sequence 协议的调用方法。例如,在下面添加类似下面的内容会从上面的屏幕截图中产生一条错误消息。但是我还没有找到解决方案。

    class De {
        let de = "de"
    }

    let de = De()
    var ar = WeakArray<De>([])
    ar.append(de)
    ar.append(de)

    ar.forEach({ $0 })

1 个答案:

答案 0 :(得分:0)

我相信SDK会在某处重新定义“元素”。将Element重命名为T应该可以解决该问题。

import Foundation

final class WeakBox<T:AnyObject> {
    weak var unbox: T?
    init(_ value: T?) {
        unbox = value
    }
}

struct WeakArray<T: AnyObject> {
    private var items: [WeakBox<T>] = []

    init(_ elements: [T]) {
        items = elements.map { WeakBox($0) }
    }

    init(_ elements: [T?]) {
        items = elements.map { WeakBox($0) }
    }

    mutating func append(_ obj:T?) {
        items.append(WeakBox(obj))
    }

    mutating func remove(at:Int) {
        items.remove(at: at)
    }
}

extension WeakArray: Collection {
    var startIndex: Int { return items.startIndex }
    var endIndex: Int { return items.endIndex }

    subscript(_ index: Int) -> T? {
        return items[index].unbox
    }

    func index(after idx: Int) -> Int {
        return items.index(after: idx)
    }
}