当我正在使用实现一个保持对其元素的弱引用的Array时,在使用Collection
扩展方法的方法之前,我偶然发现了编译错误,然后才使用Collection
方法代码编译正确且预期。
代码应该编译没有错误。
编译器抛出以下两个错误:
我找到的唯一解决方案是将属性项公开,并使用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
协议的方法,例如:
objects.forEach({ $0?.view.backgroundColor = .white })
此代码不会使用Swift 4.1在Xcode版本9.3.1(9E501)的版本上进行编译
上述代码的解决方案可在以下链接中找到:
提前感谢您提供的任何帮助。这篇文章经过全面编辑,符合Stackoverflow提出问题的标准。特别感谢MartinR指导我在Stackoverflow上发布一个好问题。
答案 0 :(得分:2)
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)
}
}