Blog

Swift Tip: Weak Arrays

In Swift Talk 81 we created a queue that only references the objects in the queue weakly. Normally a collection references its elements strongly (we're assuming that the elements are objects), so we need to create a wrapper around each element that breaks the strong reference:

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

							

Using WeakBox we can turn any strong reference into a weak one:

								let instance = UIView()
let weakReference = WeakBox(instance)

							

In order to make an array reference its elements weakly, we simply wrap all the elements:

								let strongArray = [UIView(), UIView()]
let weakArray = strongArray.map { WeakBox($0) }

							

To abstract away the mechanics of wrapping and unwrapping elements in WeakBoxes, we can introduce a lightweight wrapper around an array that takes care of that for us:

								struct WeakArray<Element: AnyObject> {
    private var items: [WeakBox<Element>] = []
    
    init(_ elements: [Element]) {
        items = elements.map { WeakBox($0) }
    }
}

							

To benefit from all the usual functionality we're used to from Swift collections, we make WeakArray conform to the Collection protocol:

								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)
    }
}

							

Now we can use WeakArray like any other collection, e.g. calling filter on it, or using its first and last properties

								let weakArray = WeakArray([UIView(), UIView()])
let firstElement = weakArray.filter { $0 != nil }.first

							

Can you guess the value of firstElement?

For an application of this technique, watch last week's Swift Talk or read the transcript. This week, we're taking a holiday break and won't release a new episode.

Stay up-to-date with our newsletter or follow us on Twitter .

Back to the Blog

Recent Posts