Skip to content

Instantly share code, notes, and snippets.

@drosenstark
Created November 18, 2018 22:04
Show Gist options
  • Save drosenstark/e27f14eb43f834eaafca141434af3ae7 to your computer and use it in GitHub Desktop.
Save drosenstark/e27f14eb43f834eaafca141434af3ae7 to your computer and use it in GitHub Desktop.
Hold protocolized objects weakly (with just a few, minor changes)
@objc public protocol Equalable: class {
@objc func isEqual(_ object: Any?) -> Bool
}
/// Store AnyObject subclasses weakly
/// * Note: if you wish to use a protocol, it must:
/// - be marked with `@objc`
/// - have all methods marked with `@objc`
/// - refine Equalable
public struct WeakArray<Element: Equalable> {
private var items: [WeakBox<Element>] = []
public init(_ elements: [Element]? = nil) {
guard let elements = elements else { return }
items = elements.map { WeakBox($0) }
}
public mutating func append(_ newElement: Element) {
let box = WeakBox(newElement)
items.append(box)
}
public mutating func remove(_ element: Element) {
items.removeAll { item in
return item.unbox?.isEqual(element) ?? false
}
}
public var unboxed: [Element] {
let filtered = items.filter { $0.unbox != nil }
return filtered.compactMap { $0.unbox }
}
public var boxedCount: Int {
return items.count
}
}
extension WeakArray: Collection {
public var startIndex: Int { return items.startIndex }
public var endIndex: Int { return items.endIndex }
public subscript(_ index: Int) -> Element? {
return items[index].unbox
}
public func index(after idx: Int) -> Int {
return items.index(after: idx)
}
}
private final class WeakBox<T: Equalable> {
weak var unbox: T?
init(_ value: T) {
unbox = value
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment