As I was working with implementing an Array that keeps weak references to its elements I stumbled on a Compile Error as soon as I used the methods of the Collection
extension methods, before using the Collection
method the code compiled correctly and expectedly.
The code should compile with no error.
The compiler throws the two following Errors:
The only solution I found is to make the property items public and use a for-loop instead of the Collection
extensions methods. After doing this the compiler was able to infer the type for items
and even the Collection
methods worked.
First implement the WeakRef
class:
final class WeakRef<T: AnyObject> {
weak var value: T?
init(_ value: T) {
self.value = value
}
}
Second implement the WeakArray
struct:
struct WeakArray<Element: AnyObject> {
public var items: [WeakRef<Element>] = []
init(_ elements: [Element]) {
items = elements.map { WeakRef($0) }
}
}
Third implement the Collection
extension implementation:
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)
}
}
Fourth create an instance of the WeakArray property not in the same source file however as WeakArray
for example:
var objects: WeakArray<UIViewController> = WeakArray.init([])
Fifth and final step call a method of the Collection
protocol for example:
objects.forEach({ $0?.view.backgroundColor = .white })
This code won't compile on the version of Xcode Version 9.3.1 (9E501) using Swift 4.1
The solution for the above code was found in the following links:
Thank you in advance to any help provided. This post was completely edited to fit Stackoverflow standards of asking a question. Special thanks to MartinR for guiding me to post a good question on Stackoverflow.
A Collection
has an associated Element
type, and that seems to conflict with your generic Element
placeholder. Using a different name E
for the placeholder solves the problem:
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)
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.