mirror of
https://github.com/JohnEstropia/CoreStore.git
synced 2026-01-17 14:37:11 +01:00
Magical NSFetchedResultsController bugfix....
This commit is contained in:
@@ -63,7 +63,7 @@ public enum CoreStore {
|
||||
|
||||
// MARK: Private
|
||||
|
||||
private static let defaultStackBarrierQueue = DispatchQueue(concurrentWith: "com.coreStore.defaultStackBarrierQueue")
|
||||
private static let defaultStackBarrierQueue = DispatchQueue.concurrent("com.coreStore.defaultStackBarrierQueue")
|
||||
|
||||
private static var defaultStackInstance: DataStack?
|
||||
}
|
||||
|
||||
@@ -45,9 +45,18 @@ internal final class CoreStoreFetchRequest<T: NSFetchRequestResult>: NSFetchRequ
|
||||
// MARK: NSFetchRequest
|
||||
|
||||
@objc
|
||||
override var affectedStores: [NSPersistentStore]? {
|
||||
dynamic override var affectedStores: [NSPersistentStore]? {
|
||||
|
||||
get { return super.affectedStores }
|
||||
set { super.affectedStores = newValue }
|
||||
get {
|
||||
|
||||
return super.affectedStores
|
||||
// let affectedStores: NSArray? = super.affectedStores.flatMap({ NSArray(array: $0) } )
|
||||
// return affectedStores as? [NSPersistentStore]
|
||||
}
|
||||
set {
|
||||
|
||||
super.affectedStores = newValue
|
||||
// super.affectedStores = newValue.flatMap(Array.init)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,9 +30,10 @@ import Foundation
|
||||
|
||||
internal extension DispatchQueue {
|
||||
|
||||
internal convenience init(serialWith label: String, qos: DispatchQoS = .default) {
|
||||
@nonobjc
|
||||
internal static func serial(_ label: String, qos: DispatchQoS = .default) -> DispatchQueue {
|
||||
|
||||
self.init(
|
||||
return DispatchQueue(
|
||||
label: label,
|
||||
qos: qos,
|
||||
attributes: [],
|
||||
@@ -41,9 +42,10 @@ internal extension DispatchQueue {
|
||||
)
|
||||
}
|
||||
|
||||
internal convenience init(concurrentWith label: String, qos: DispatchQoS = .default) {
|
||||
@nonobjc
|
||||
internal static func concurrent(_ label: String, qos: DispatchQoS = .default) -> DispatchQueue {
|
||||
|
||||
self.init(
|
||||
return DispatchQueue(
|
||||
label: label,
|
||||
qos: qos,
|
||||
attributes: .concurrent,
|
||||
@@ -52,6 +54,7 @@ internal extension DispatchQueue {
|
||||
)
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func cs_isCurrentExecutionContext() -> Bool {
|
||||
|
||||
let specific = ObjectIdentifier(self)
|
||||
@@ -60,21 +63,25 @@ internal extension DispatchQueue {
|
||||
return DispatchQueue.getSpecific(key: Static.specificKey) == specific
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func cs_sync<T>(_ closure: () throws -> T) rethrows -> T {
|
||||
|
||||
return try self.sync { try autoreleasepool(invoking: closure) }
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func cs_async(_ closure: @escaping () -> Void) {
|
||||
|
||||
self.async { autoreleasepool(invoking: closure) }
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func cs_barrierSync<T>(_ closure: () throws -> T) rethrows -> T {
|
||||
|
||||
return try self.sync(flags: .barrier) { try autoreleasepool(invoking: closure) }
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func cs_barrierAsync(_ closure: @escaping () -> Void) {
|
||||
|
||||
self.async(flags: .barrier) { autoreleasepool(invoking: closure) }
|
||||
|
||||
@@ -108,7 +108,7 @@ internal final class FetchedResultsControllerDelegate<EntityType: NSManagedObjec
|
||||
return
|
||||
}
|
||||
|
||||
guard let actualType = NSFetchedResultsChangeType(rawValue: type.rawValue) else {
|
||||
guard var actualType = NSFetchedResultsChangeType(rawValue: type.rawValue) else {
|
||||
|
||||
// This fix is for a bug where iOS passes 0 for NSFetchedResultsChangeType, but this is not a valid enum case.
|
||||
// Swift will then always execute the first case of the switch causing strange behaviour.
|
||||
@@ -123,19 +123,12 @@ internal final class FetchedResultsControllerDelegate<EntityType: NSManagedObjec
|
||||
|
||||
if #available(iOS 10.0, tvOS 10.0, watchOS 3.0, *) {
|
||||
|
||||
// iOS 10 is better, but still not perfect...
|
||||
// I don't know if iOS 10 even attempted to fix this mess...
|
||||
if case .update = actualType,
|
||||
let indexPath = indexPath,
|
||||
let newIndexPath = newIndexPath {
|
||||
indexPath != nil,
|
||||
newIndexPath != nil {
|
||||
|
||||
self.handler?.controller(
|
||||
controller,
|
||||
didChangeObject: anObject,
|
||||
atIndexPath: indexPath,
|
||||
forChangeType: .move,
|
||||
newIndexPath: newIndexPath
|
||||
)
|
||||
return
|
||||
actualType = .move
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -147,7 +147,7 @@ internal extension NSManagedObjectContext {
|
||||
}
|
||||
|
||||
@nonobjc
|
||||
internal func saveAsynchronouslyWithCompletion(_ completion: ((_ result: SaveResult) -> Void) = { _ in }) {
|
||||
internal func saveAsynchronouslyWithCompletion(_ completion: @escaping ((_ result: SaveResult) -> Void) = { _ in }) {
|
||||
|
||||
self.perform {
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ internal final class NotificationObserver {
|
||||
|
||||
let observer: NSObjectProtocol
|
||||
|
||||
init(notificationName: Notification.Name, object: AnyObject?, queue: OperationQueue? = nil, closure: @escaping (_ note: Notification) -> Void) {
|
||||
init(notificationName: Notification.Name, object: Any?, queue: OperationQueue? = nil, closure: @escaping (_ note: Notification) -> Void) {
|
||||
|
||||
self.observer = NotificationCenter.default.addObserver(
|
||||
forName: notificationName,
|
||||
|
||||
@@ -385,18 +385,15 @@ public final class DataStack {
|
||||
internal let mainContext: NSManagedObjectContext
|
||||
internal let model: NSManagedObjectModel
|
||||
internal let migrationChain: MigrationChain
|
||||
internal let childTransactionQueue = DispatchQueue(serialWith: "com.coreStore.dataStack.childTransactionQueue")
|
||||
internal let storeMetadataUpdateQueue = DispatchQueue(concurrentWith: "com.coreStore.persistentStoreBarrierQueue")
|
||||
internal let childTransactionQueue = DispatchQueue.serial("com.coreStore.dataStack.childTransactionQueue")
|
||||
internal let storeMetadataUpdateQueue = DispatchQueue.concurrent("com.coreStore.persistentStoreBarrierQueue")
|
||||
internal let migrationQueue: OperationQueue = {
|
||||
|
||||
let migrationQueue = OperationQueue()
|
||||
migrationQueue.maxConcurrentOperationCount = 1
|
||||
migrationQueue.name = "com.coreStore.migrationOperationQueue"
|
||||
migrationQueue.qualityOfService = .utility
|
||||
migrationQueue.underlyingQueue = DispatchQueue(
|
||||
serialWith: "com.coreStore.migrationQueue",
|
||||
qos: .userInitiated
|
||||
)
|
||||
migrationQueue.underlyingQueue = DispatchQueue.serial("com.coreStore.migrationQueue", qos: .userInitiated)
|
||||
return migrationQueue
|
||||
}()
|
||||
|
||||
|
||||
@@ -451,7 +451,7 @@ public /*abstract*/ class BaseDataTransaction {
|
||||
|
||||
internal let context: NSManagedObjectContext
|
||||
internal let transactionQueue: DispatchQueue
|
||||
internal let childTransactionQueue = DispatchQueue(serialWith: "com.corestore.datastack.childtransactionqueue")
|
||||
internal let childTransactionQueue = DispatchQueue.serial("com.corestore.datastack.childtransactionqueue")
|
||||
internal let supportsUndo: Bool
|
||||
internal let bypassesQueueing: Bool
|
||||
|
||||
|
||||
@@ -69,10 +69,7 @@ public extension DataStack {
|
||||
|
||||
return UnsafeDataTransaction(
|
||||
mainContext: self.rootSavingContext,
|
||||
queue: DispatchQueue(
|
||||
serialWith: "com.coreStore.dataStack.unsafeTransactionQueue",
|
||||
qos: .userInitiated
|
||||
),
|
||||
queue: DispatchQueue.serial("com.coreStore.dataStack.unsafeTransactionQueue", qos: .userInitiated),
|
||||
supportsUndo: supportsUndo
|
||||
)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user