Created
November 18, 2018 22:04
-
-
Save drosenstark/e27f14eb43f834eaafca141434af3ae7 to your computer and use it in GitHub Desktop.
Hold protocolized objects weakly (with just a few, minor changes)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
@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