当我正在实现一个保持对其元素的弱引用的数组时,在使用 之前,我在使用
方法正确且按预期编译的代码。Collection
扩展方法时偶然发现了一个编译错误Collection
预期行为
代码应该可以正确编译。
当前行为
编译器抛出以下两个错误:
- WeakRef 需要那个元素?成为类(class)类型
- 无法推断“项目”的类型
可能的解决方案
我找到的唯一解决方案是公开属性项并使用 for 循环而不是 Collection
扩展方法。完成此操作后,编译器能够推断出 items
的类型,甚至 Collection
方法也能正常工作。
重现步骤
首先实现WeakRef
类:
final class WeakRef<T: AnyObject> {
weak var value: T?
init(_ value: T) {
self.value = value
}
}
第二个实现 WeakArray
结构:
struct WeakArray<Element: AnyObject> {
public var items: [WeakRef<Element>] = []
init(_ elements: [Element]) {
items = elements.map { WeakRef($0) }
}
}
第三个实现Collection
扩展实现:
extension WeakArray: Collection {
var startIndex: Int { return items.startIndex }
var endIndex: Int { return items.endIndex }
subscript(_ index: Int) -> Element? {
return items[index].value
}
func index(after idx: Int) -> Int {
return items.index(after: idx)
}
}
第四次创建 WeakArray 属性的实例,但不在同一个源文件中,而是作为 WeakArray
例如:
var objects: WeakArray<UIViewController> = WeakArray.init([])
第五步也是最后一步调用 Collection
协议(protocol)的方法,例如:
objects.forEach({ $0?.view.backgroundColor = .white })
上下文(环境)
此代码无法在使用 Swift 4.1 的 Xcode 版本 9.3.1 (9E501) 上编译
附加说明
上述代码的解决方案在以下链接中找到:
- https://marcosantadev.com/swift-arrays-holding-elements-weak-references/
- https://www.objc.io/blog/2017/12/28/weak-arrays/
提前感谢您提供的任何帮助。这篇文章经过完全编辑以符合 Stackoverflow 提出问题的标准。特别感谢 MartinR 指导我在 Stackoverflow 上发布了一个很好的问题。
最佳答案
一个 Collection
有一个关联的 Element
类型,这似乎
与您的通用 Element
占位符冲突。使用不同的
占位符的名称 E
解决了这个问题:
struct WeakArray<E: AnyObject> {
public var items: [WeakRef<E>] = []
init(_ elements: [E]) {
items = elements.map { WeakRef($0) }
}
}
extension WeakArray: Collection {
var startIndex: Int { return items.startIndex }
var endIndex: Int { return items.endIndex }
subscript(_ index: Int) -> E? {
return items[index].value
}
func index(after idx: Int) -> Int {
return items.index(after: idx)
}
}
关于arrays - 当元素明显受限时,为什么 Swift 编译器在推断我的通用元素的类型时会抛出错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50487948/