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 = { 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 = { 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