Skip to content

Instantly share code, notes, and snippets.

@ha1f
Created October 10, 2019 03:54
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ha1f/ae8f6a5d1c3fa288b594ea5d7688f950 to your computer and use it in GitHub Desktop.
Save ha1f/ae8f6a5d1c3fa288b594ea5d7688f950 to your computer and use it in GitHub Desktop.
//
// UIViewControllerReferenceCycleTests.swift
// TargetTests
//
import UIKit
import XCTest
@testable import Target
final class UIViewControllerReferenceCycleTests: XCTestCase {
private func _testViewController(_ builder: @escaping @autoclosure () -> UIViewController) {
let exp = expectation(description: "viewController should be deallocated.")
DispatchQueue.main.async {
let viewController = builder()
viewController.loadViewIfNeeded()
viewController.deallocNotifier.observe {
exp.fulfill()
}
}
wait(for: [exp], timeout: 1.0)
}
func testViewController() {
_testViewController(ViewController())
}
}
private final class DeallocNotifier {
private var _observers: [() -> Void] = []
func observe(_ observer: @escaping () -> Void) {
_observers.append(observer)
}
deinit {
_observers.forEach { observer in
observer()
}
}
}
private var deallocNotifierContext: UInt8 = 0
extension NSObject {
fileprivate var deallocNotifier: DeallocNotifier {
/// This is a technique to use getter as if this object has additional property
if let notifier = objc_getAssociatedObject(self, &deallocNotifierContext) as? DeallocNotifier {
return notifier
}
let notifier = DeallocNotifier()
objc_setAssociatedObject(
self,
&deallocNotifierContext,
notifier,
.OBJC_ASSOCIATION_RETAIN_NONATOMIC
)
return notifier
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment