From f055c54a6684807f8843bbff936226f17a020381 Mon Sep 17 00:00:00 2001 From: Ruslan Skorb Date: Fri, 24 Mar 2017 21:30:46 +0200 Subject: [PATCH 1/3] [ListMonitor] Use `dynamicCast()` to cast `fetchedObjects` to `[T]?` without checking the type. Type checking takes a time. So there is a performance problem when casting a large number of fetched objects to an array of a certain type using the operator `as?`. --- Sources/Observing/ListMonitor.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/Observing/ListMonitor.swift b/Sources/Observing/ListMonitor.swift index ad96481..342f211 100644 --- a/Sources/Observing/ListMonitor.swift +++ b/Sources/Observing/ListMonitor.swift @@ -202,7 +202,7 @@ public final class ListMonitor: Hashable { !self.isPendingRefetch || Thread.isMainThread, "Attempted to access a \(cs_typeName(self)) outside the main thread while a refetch is in progress." ) - return (self.fetchedResultsController.fetchedObjects as? [T]) ?? [] + return self.fetchedResultsController.dynamicCast().fetchedObjects ?? [] } /** @@ -371,7 +371,7 @@ public final class ListMonitor: Hashable { !self.isPendingRefetch || Thread.isMainThread, "Attempted to access a \(cs_typeName(self)) outside the main thread while a refetch is in progress." ) - return (self.fetchedResultsController.fetchedObjects as? [T] ?? []).index(of: object) + return (self.fetchedResultsController.dynamicCast().fetchedObjects ?? []).index(of: object) } /** From 881ee4af0aa81367f394400c3922f948c67524d6 Mon Sep 17 00:00:00 2001 From: John Estropia Date: Thu, 9 Mar 2017 18:59:37 +0900 Subject: [PATCH 2/3] remove warnings when calling unsafeBitCast() --- CoreStoreTests/ListObserverTests.swift | 15 +++++++++++++++ CoreStoreTests/ObjectObserverTests.swift | 22 +++++++++++++++++++++- Sources/Observing/ListMonitor.swift | 7 ++++++- Sources/Observing/ObjectMonitor.swift | 17 ++++++++++++++++- 4 files changed, 58 insertions(+), 3 deletions(-) diff --git a/CoreStoreTests/ListObserverTests.swift b/CoreStoreTests/ListObserverTests.swift index 987d4de..f84cd4c 100644 --- a/CoreStoreTests/ListObserverTests.swift +++ b/CoreStoreTests/ListObserverTests.swift @@ -35,6 +35,21 @@ import CoreStore class ListObserverTests: BaseTestDataTestCase { + @objc + dynamic func test_ThatListObservers_CanDowncast() { + + self.prepareStack { (stack) in + + let monitor = stack.monitorSectionedList( + From(), + SectionBy(#keyPath(TestEntity1.testBoolean)), + OrderBy(.ascending(#keyPath(TestEntity1.testBoolean)), .ascending(#keyPath(TestEntity1.testEntityID))) + ) + let downcast = monitor.downcast() + XCTAssertTrue(monitor == downcast) + } + } + @objc dynamic func test_ThatListObservers_CanReceiveInsertNotifications() { diff --git a/CoreStoreTests/ObjectObserverTests.swift b/CoreStoreTests/ObjectObserverTests.swift index 7884462..e2fa9f8 100644 --- a/CoreStoreTests/ObjectObserverTests.swift +++ b/CoreStoreTests/ObjectObserverTests.swift @@ -33,7 +33,27 @@ import CoreStore // MARK: - ObjectObserverTests -class ObjectObserverTests: BaseTestDataTestCase { + class ObjectObserverTests: BaseTestDataTestCase { + + @objc + dynamic func test_ThatObjectObservers_CanDowncast() { + + self.prepareStack { (stack) in + + self.prepareTestDataForStack(stack) + + guard let object = stack.fetchOne( + From(), + Where(#keyPath(TestEntity1.testEntityID), isEqualTo: 101)) else { + + XCTFail() + return + } + let monitor = stack.monitorObject(object) + let downcast = monitor.downcast() + XCTAssertTrue(monitor == downcast) + } + } @objc dynamic func test_ThatObjectObservers_CanReceiveUpdateNotifications() { diff --git a/Sources/Observing/ListMonitor.swift b/Sources/Observing/ListMonitor.swift index 342f211..e9272a9 100644 --- a/Sources/Observing/ListMonitor.swift +++ b/Sources/Observing/ListMonitor.swift @@ -677,7 +677,12 @@ public final class ListMonitor: Hashable { internal func downcast() -> ListMonitor { - return unsafeBitCast(self, to: ListMonitor.self) + @inline(__always) + func noWarnUnsafeBitCast(_ x: T, to type: U.Type) -> U { + + return unsafeBitCast(x, to: type) + } + return noWarnUnsafeBitCast(self, to: ListMonitor.self) } internal func registerChangeNotification(_ notificationKey: UnsafeRawPointer, name: Notification.Name, toObserver observer: AnyObject, callback: @escaping (_ monitor: ListMonitor) -> Void) { diff --git a/Sources/Observing/ObjectMonitor.swift b/Sources/Observing/ObjectMonitor.swift index 9956a75..88adf35 100644 --- a/Sources/Observing/ObjectMonitor.swift +++ b/Sources/Observing/ObjectMonitor.swift @@ -110,11 +110,21 @@ public final class ObjectMonitor: Equatable { return lhs === rhs } + public static func == (lhs: ObjectMonitor, rhs: ObjectMonitor) -> Bool { + + return lhs.fetchedResultsController === rhs.fetchedResultsController + } + public static func ~= (lhs: ObjectMonitor, rhs: ObjectMonitor) -> Bool { return lhs === rhs } + public static func ~= (lhs: ObjectMonitor, rhs: ObjectMonitor) -> Bool { + + return lhs.fetchedResultsController === rhs.fetchedResultsController + } + // MARK: Hashable @@ -212,7 +222,12 @@ public final class ObjectMonitor: Equatable { internal func downcast() -> ObjectMonitor { - return unsafeBitCast(self, to: ObjectMonitor.self) + @inline(__always) + func noWarnUnsafeBitCast(_ x: T, to type: U.Type) -> U { + + return unsafeBitCast(x, to: type) + } + return noWarnUnsafeBitCast(self, to: ObjectMonitor.self) } deinit { From 716e0699840c3e4545525c0d9cf737b6d4779652 Mon Sep 17 00:00:00 2001 From: John Estropia Date: Tue, 28 Mar 2017 11:25:24 +0900 Subject: [PATCH 3/3] version bump --- CoreStore.podspec | 2 +- CoreStore.xcodeproj/project.pbxproj | 20 ++++++++++---------- Sources/Info.plist | 2 +- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/CoreStore.podspec b/CoreStore.podspec index b4539d4..e733028 100644 --- a/CoreStore.podspec +++ b/CoreStore.podspec @@ -1,6 +1,6 @@ Pod::Spec.new do |s| s.name = "CoreStore" - s.version = "3.0.3" + s.version = "3.1.0" s.license = "MIT" s.summary = "Unleashing the real power of Core Data with the elegance and safety of Swift" s.homepage = "https://github.com/JohnEstropia/CoreStore" diff --git a/CoreStore.xcodeproj/project.pbxproj b/CoreStore.xcodeproj/project.pbxproj index 856048e..bd86ad5 100644 --- a/CoreStore.xcodeproj/project.pbxproj +++ b/CoreStore.xcodeproj/project.pbxproj @@ -1114,7 +1114,7 @@ B5F1DA8C1B9AA97D007C5CBB /* ImportableObject.swift */, B5F1DA8F1B9AA991007C5CBB /* ImportableUniqueObject.swift */, B5E834B81B76311F001D3D50 /* BaseDataTransaction+Importing.swift */, - B509C7F31E54511B0061C547 /* CoreStoreUniqueIDAttributeType.swift */, + B509C7F31E54511B0061C547 /* CoreStoreImportableAttributeType.swift */, ); path = Importing; sourceTree = ""; @@ -1164,7 +1164,7 @@ B5E84F071AFF847B0064E85B /* CoreStore+Querying.swift */, B596BBB51DD5BC67001DCDD9 /* FetchableSource.swift */, B596BBBA1DD5C39F001DCDD9 /* QueryableSource.swift */, - B549F65D1E569C7400FBAB2D /* CoreStoreQueryingAttributeType.swift */, + B549F65D1E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift */, B5E84F0A1AFF847B0064E85B /* Protocol Clauses */, B5E84EFF1AFF847B0064E85B /* Concrete Clauses */, ); @@ -1593,7 +1593,7 @@ B5E1B59D1CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */, B5ECDC231CA81A3900C7F112 /* CSCoreStore+Querying.swift in Sources */, B549F6731E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */, - B509C7F41E54511B0061C547 /* CoreStoreUniqueIDAttributeType.swift in Sources */, + B509C7F41E54511B0061C547 /* CoreStoreImportableAttributeType.swift in Sources */, B5E84F0E1AFF847B0064E85B /* Tweak.swift in Sources */, B5E1B5931CAA0C15007FD580 /* CSObjectMonitor.swift in Sources */, B5ECDC291CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */, @@ -1665,7 +1665,7 @@ B5E84F301AFF849C0064E85B /* NSManagedObjectContext+CoreStore.swift in Sources */, B546F9691C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */, B53FBA1E1CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */, - B549F65E1E569C7400FBAB2D /* CoreStoreQueryingAttributeType.swift in Sources */, + B549F65E1E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift in Sources */, B5E84F211AFF84860064E85B /* CoreStore+Observing.swift in Sources */, B559CD431CAA8B6300E4D58B /* CSSetupResult.swift in Sources */, B5FE4DA71C84FB4400FA6A91 /* InMemoryStore.swift in Sources */, @@ -1749,7 +1749,7 @@ B5E1B59F1CAA2568007FD580 /* CSDataStack+Observing.swift in Sources */, B5ECDC251CA81A3900C7F112 /* CSCoreStore+Querying.swift in Sources */, B549F6741E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */, - B509C7F51E54511B0061C547 /* CoreStoreUniqueIDAttributeType.swift in Sources */, + B509C7F51E54511B0061C547 /* CoreStoreImportableAttributeType.swift in Sources */, 82BA18B31C4BBD3900A0916E /* ImportableUniqueObject.swift in Sources */, B5E1B5951CAA0C15007FD580 /* CSObjectMonitor.swift in Sources */, B5ECDC2B1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */, @@ -1821,7 +1821,7 @@ B546F96A1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */, B53FBA201CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */, 82BA18A81C4BBD2900A0916E /* CoreStoreLogger.swift in Sources */, - B549F65F1E569C7400FBAB2D /* CoreStoreQueryingAttributeType.swift in Sources */, + B549F65F1E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift in Sources */, B559CD451CAA8B6300E4D58B /* CSSetupResult.swift in Sources */, 82BA18B81C4BBD4200A0916E /* ClauseTypes.swift in Sources */, B5ECDBEE1CA6BF2000C7F112 /* CSFrom.swift in Sources */, @@ -1905,7 +1905,7 @@ B559CD471CAA8B6300E4D58B /* CSSetupResult.swift in Sources */, B5ECDBF01CA6BF2000C7F112 /* CSFrom.swift in Sources */, B549F6761E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */, - B509C7F71E54511B0061C547 /* CoreStoreUniqueIDAttributeType.swift in Sources */, + B509C7F71E54511B0061C547 /* CoreStoreImportableAttributeType.swift in Sources */, B5220E1F1D130810009BC71E /* CSListObserver.swift in Sources */, B52DD1941BE1F92500949AFE /* CoreStore.swift in Sources */, B52DD1A61BE1F92F00949AFE /* BaseDataTransaction+Importing.swift in Sources */, @@ -1977,7 +1977,7 @@ B52DD1BB1BE1F94000949AFE /* MigrationType.swift in Sources */, B52DD1C91BE1F94600949AFE /* NSManagedObjectContext+Transaction.swift in Sources */, B5220E151D130663009BC71E /* CoreStore+Observing.swift in Sources */, - B549F6611E569C7400FBAB2D /* CoreStoreQueryingAttributeType.swift in Sources */, + B549F6611E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift in Sources */, B52DD19B1BE1F92800949AFE /* CoreStoreLogger.swift in Sources */, B52DD1991BE1F92800949AFE /* DefaultLogger.swift in Sources */, B5220E201D130813009BC71E /* CSObjectMonitor.swift in Sources */, @@ -2061,7 +2061,7 @@ B5ECDC261CA81A3900C7F112 /* CSCoreStore+Querying.swift in Sources */, B563217F1BD65216006C9394 /* CoreStore.swift in Sources */, B549F6751E56A92800FBAB2D /* CoreDataNativeType.swift in Sources */, - B509C7F61E54511B0061C547 /* CoreStoreUniqueIDAttributeType.swift in Sources */, + B509C7F61E54511B0061C547 /* CoreStoreImportableAttributeType.swift in Sources */, B5E1B5961CAA0C15007FD580 /* CSObjectMonitor.swift in Sources */, B5ECDC2C1CA81CC700C7F112 /* CSDataStack+Transaction.swift in Sources */, B56321911BD65216006C9394 /* BaseDataTransaction+Importing.swift in Sources */, @@ -2133,7 +2133,7 @@ B546F96B1C9AF26D00D5AC55 /* CSInMemoryStore.swift in Sources */, B53FBA211CAB63FA00F0D40A /* NSFetchedResultsController+ObjectiveC.swift in Sources */, B563218B1BD65216006C9394 /* UnsafeDataTransaction.swift in Sources */, - B549F6601E569C7400FBAB2D /* CoreStoreQueryingAttributeType.swift in Sources */, + B549F6601E569C7400FBAB2D /* CoreStoreQueryableAttributeType.swift in Sources */, B559CD461CAA8B6300E4D58B /* CSSetupResult.swift in Sources */, B56321A61BD65216006C9394 /* MigrationType.swift in Sources */, B5ECDBEF1CA6BF2000C7F112 /* CSFrom.swift in Sources */, diff --git a/Sources/Info.plist b/Sources/Info.plist index 0ea7266..543e5f9 100644 --- a/Sources/Info.plist +++ b/Sources/Info.plist @@ -15,7 +15,7 @@ CFBundlePackageType FMWK CFBundleShortVersionString - 3.0.3 + 3.1.0 CFBundleSignature ???? CFBundleVersion