From 7ce5a5ebdb6cf039c33ddfd2f5b4082d12f9bcf6 Mon Sep 17 00:00:00 2001 From: Peter Livesey Date: Tue, 7 Jun 2016 09:34:17 -0700 Subject: [PATCH] Adding timing capabilities to clean memory (#5) Adding timing capabilities to clean memory This will enable projects to time how long garbage collection is taking --- ConsistencyManager/ConsistencyManager.swift | 18 +++++++++++++++++ .../MemoryWarningTests.swift | 20 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/ConsistencyManager/ConsistencyManager.swift b/ConsistencyManager/ConsistencyManager.swift index c1c7e01..0ee2783 100644 --- a/ConsistencyManager/ConsistencyManager.swift +++ b/ConsistencyManager/ConsistencyManager.swift @@ -65,6 +65,22 @@ public class ConsistencyManager { */ public var garbageCollectionInterval: NSTimeInterval = 300 + // MARK: Constants + + /** + This notification is fired whenever the asynchronous work of clean memory starts. + It's useful if you want to add timers to this work. + Called on an internal thread. + */ + public static let kCleanMemoryAsynchronousWorkStarted = "com.linkedin.consistencyManager.kCleanMemoryAsynchronousWorkStarted" + + /** + This notification is fired whenever the asynchronous work of clean memory finishes. + It's useful if you want to add timers to this work. + Called on an internal thread. + */ + public static let kCleanMemoryAsynchronousWorkFinished = "com.linkedin.consistencyManager.kCleanMemoryAsynchronousWorkFinished" + // MARK: - Private ivars /** @@ -343,6 +359,7 @@ public class ConsistencyManager { */ public func cleanMemory() { dispatch_async(dispatchQueue) { + NSNotificationCenter.defaultCenter().postNotificationName(ConsistencyManager.kCleanMemoryAsynchronousWorkStarted, object: self) for (key, var listenersArray) in self.listeners { listenersArray.prune() // If the array has no elements now, let's remove it from the dictionary @@ -353,6 +370,7 @@ public class ConsistencyManager { self.listeners[key] = listenersArray } } + NSNotificationCenter.defaultCenter().postNotificationName(ConsistencyManager.kCleanMemoryAsynchronousWorkFinished, object: self) } // Remove any PausedListener structs from our local list if the internal listener is now nil pausedListeners = self.pausedListeners.filter { $0.listener != nil } diff --git a/ConsistencyManagerTests/MemoryWarningTests.swift b/ConsistencyManagerTests/MemoryWarningTests.swift index c4441c0..522fb42 100644 --- a/ConsistencyManagerTests/MemoryWarningTests.swift +++ b/ConsistencyManagerTests/MemoryWarningTests.swift @@ -13,7 +13,21 @@ import XCTest class MemoryWarningTests: ConsistencyManagerTestCase { + var cleanMemoryStartedTimes = [NSDate]() + var cleanMemoryFinishedTimes = [NSDate]() + + func testMemoryWarning() { + let testStart = NSDate() + + NSNotificationCenter.defaultCenter().addObserverForName(ConsistencyManager.kCleanMemoryAsynchronousWorkStarted, object: nil, queue: nil) { _ in + self.cleanMemoryStartedTimes.append(NSDate()) + } + + NSNotificationCenter.defaultCenter().addObserverForName(ConsistencyManager.kCleanMemoryAsynchronousWorkFinished, object: nil, queue: nil) { _ in + self.cleanMemoryFinishedTimes.append(NSDate()) + } + let model = TestRequiredModel(id: "0", data: 0) // Setting this up with a block ensures that the listener will be released and is out of scope. @@ -42,5 +56,11 @@ class MemoryWarningTests: ConsistencyManagerTestCase { XCTAssertEqual(listenersArray.count, 0) } // Else it's nil which is fine too + + // Now, let's check we got the right start/finish times + XCTAssertEqual(cleanMemoryStartedTimes.count, 1) + XCTAssertEqual(cleanMemoryFinishedTimes.count, 1) + XCTAssertTrue(cleanMemoryStartedTimes[0].timeIntervalSince1970 <= cleanMemoryFinishedTimes[0].timeIntervalSince1970) + XCTAssertTrue(testStart.timeIntervalSince1970 <= cleanMemoryStartedTimes[0].timeIntervalSince1970) } }