Compare commits

..

1 Commits
3.0.2 ... 3.0.3

Author SHA1 Message Date
John Estropia
03973790a8 revert recent swizzling update. sorry about that 2017-02-10 20:33:07 +09:00
7 changed files with 232 additions and 222 deletions

View File

@@ -1,6 +1,6 @@
Pod::Spec.new do |s| Pod::Spec.new do |s|
s.name = "CoreStore" s.name = "CoreStore"
s.version = "3.0.2" s.version = "3.0.3"
s.license = "MIT" s.license = "MIT"
s.summary = "Unleashing the real power of Core Data with the elegance and safety of Swift" s.summary = "Unleashing the real power of Core Data with the elegance and safety of Swift"
s.homepage = "https://github.com/JohnEstropia/CoreStore" s.homepage = "https://github.com/JohnEstropia/CoreStore"

View File

@@ -378,8 +378,10 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
@@ -423,8 +425,10 @@
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES; CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES; CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES; CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES; CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";

View File

@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key> <key>CFBundlePackageType</key>
<string>FMWK</string> <string>FMWK</string>
<key>CFBundleShortVersionString</key> <key>CFBundleShortVersionString</key>
<string>3.0.2</string> <string>3.0.3</string>
<key>CFBundleSignature</key> <key>CFBundleSignature</key>
<string>????</string> <string>????</string>
<key>CFBundleVersion</key> <key>CFBundleVersion</key>

View File

@@ -31,210 +31,211 @@ import CoreData
internal extension NSManagedObject { internal extension NSManagedObject {
@nonobjc // TODO: test before release (rolled back)
internal static func cs_swizzleMethodsForLogging() { // @nonobjc
// internal static func cs_swizzleMethodsForLogging() {
struct Static { //
// struct Static {
static let isSwizzled = Static.swizzle() //
// static let isSwizzled = Static.swizzle()
private static func swizzle() -> Bool { //
// private static func swizzle() -> Bool {
NSManagedObject.cs_swizzle( //
original: #selector(NSManagedObject.willAccessValue(forKey:)), // NSManagedObject.cs_swizzle(
proxy: #selector(NSManagedObject.cs_willAccessValue(forKey:)) // original: #selector(NSManagedObject.willAccessValue(forKey:)),
) // proxy: #selector(NSManagedObject.cs_willAccessValue(forKey:))
NSManagedObject.cs_swizzle( // )
original: #selector(NSManagedObject.willChangeValue(forKey:)), // NSManagedObject.cs_swizzle(
proxy: #selector(NSManagedObject.cs_willChangeValue(forKey:)) // original: #selector(NSManagedObject.willChangeValue(forKey:)),
) // proxy: #selector(NSManagedObject.cs_willChangeValue(forKey:))
NSManagedObject.cs_swizzle( // )
original: #selector(NSManagedObject.willChangeValue(forKey:withSetMutation:using:)), // NSManagedObject.cs_swizzle(
proxy: #selector(NSManagedObject.cs_willChangeValue(forKey:withSetMutation:using:)) // original: #selector(NSManagedObject.willChangeValue(forKey:withSetMutation:using:)),
) // proxy: #selector(NSManagedObject.cs_willChangeValue(forKey:withSetMutation:using:))
return true // )
} // return true
} // }
assert(Static.isSwizzled) // }
} // assert(Static.isSwizzled)
// }
@nonobjc //
private static func cs_swizzle(original originalSelector: Selector, proxy swizzledSelector: Selector) { // @nonobjc
// private static func cs_swizzle(original originalSelector: Selector, proxy swizzledSelector: Selector) {
let originalMethod = class_getInstanceMethod(NSManagedObject.self, originalSelector) //
let swizzledMethod = class_getInstanceMethod(NSManagedObject.self, swizzledSelector) // let originalMethod = class_getInstanceMethod(NSManagedObject.self, originalSelector)
let didAddMethod = class_addMethod( // let swizzledMethod = class_getInstanceMethod(NSManagedObject.self, swizzledSelector)
NSManagedObject.self, // let didAddMethod = class_addMethod(
originalSelector, // NSManagedObject.self,
method_getImplementation(swizzledMethod), // originalSelector,
method_getTypeEncoding(swizzledMethod) // method_getImplementation(swizzledMethod),
) // method_getTypeEncoding(swizzledMethod)
if didAddMethod { // )
// if didAddMethod {
class_replaceMethod( //
NSManagedObject.self, // class_replaceMethod(
swizzledSelector, // NSManagedObject.self,
method_getImplementation(originalMethod), // swizzledSelector,
method_getTypeEncoding(originalMethod) // method_getImplementation(originalMethod),
) // method_getTypeEncoding(originalMethod)
} // )
else { // }
// else {
method_exchangeImplementations(originalMethod, swizzledMethod) //
} // method_exchangeImplementations(originalMethod, swizzledMethod)
} // }
// }
private dynamic func cs_willAccessValue(forKey key: String?) { //
// private dynamic func cs_willAccessValue(forKey key: String?) {
self.cs_willAccessValue(forKey: key) //
// self.cs_willAccessValue(forKey: key)
guard CoreStore.logger.enableObjectConcurrencyDebugging else { //
// guard CoreStore.logger.enableObjectConcurrencyDebugging else {
return //
} // return
// }
guard let context = self.managedObjectContext else { //
// guard let context = self.managedObjectContext else {
CoreStore.log( //
.warning, // CoreStore.log(
message: "Attempted to access the \"\(key ?? "")\" key of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(NSManagedObjectContext.self))." // .warning,
) // message: "Attempted to access the \"\(key ?? "")\" key of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(NSManagedObjectContext.self))."
return // )
} // return
if context.isTransactionContext { // }
// if context.isTransactionContext {
guard let transaction = context.parentTransaction else { //
// guard let transaction = context.parentTransaction else {
CoreStore.log( //
.warning, // CoreStore.log(
message: "Attempted to access the \"\(key ?? "")\" key of an object of type \(cs_typeName(self)) after has been deleted from its transaction." // .warning,
) // message: "Attempted to access the \"\(key ?? "")\" key of an object of type \(cs_typeName(self)) after has been deleted from its transaction."
return // )
} // return
CoreStore.assert( // }
transaction.isRunningInAllowedQueue(), // CoreStore.assert(
"Attempted to access the \"\(key ?? "")\" key of an object of type \(cs_typeName(self)) outside its transaction's designated queue." // transaction.isRunningInAllowedQueue(),
) // "Attempted to access the \"\(key ?? "")\" key of an object of type \(cs_typeName(self)) outside its transaction's designated queue."
return // )
} // return
if context.isDataStackContext { // }
// if context.isDataStackContext {
guard context.parentStack != nil else { //
// guard context.parentStack != nil else {
CoreStore.log( //
.warning, // CoreStore.log(
message: "Attempted to access the \"\(key ?? "")\" key of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(DataStack.self)).") // .warning,
return // message: "Attempted to access the \"\(key ?? "")\" key of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(DataStack.self)).")
} // return
CoreStore.assert( // }
Thread.isMainThread, // CoreStore.assert(
"Attempted to access the \"\(key ?? "")\" key of an object of type \(cs_typeName(self)) outside the main thread." // Thread.isMainThread,
) // "Attempted to access the \"\(key ?? "")\" key of an object of type \(cs_typeName(self)) outside the main thread."
return // )
} // return
} // }
// }
private dynamic func cs_willChangeValue(forKey key: String?) { //
// private dynamic func cs_willChangeValue(forKey key: String?) {
self.cs_willChangeValue(forKey: key) //
// self.cs_willChangeValue(forKey: key)
guard CoreStore.logger.enableObjectConcurrencyDebugging else { //
// guard CoreStore.logger.enableObjectConcurrencyDebugging else {
return //
} // return
// }
guard let context = self.managedObjectContext else { //
// guard let context = self.managedObjectContext else {
CoreStore.log( //
.warning, // CoreStore.log(
message: "Attempted to change the \"\(key ?? "")\" of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(NSManagedObjectContext.self))." // .warning,
) // message: "Attempted to change the \"\(key ?? "")\" of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(NSManagedObjectContext.self))."
return // )
} // return
if context.isTransactionContext { // }
// if context.isTransactionContext {
guard let transaction = context.parentTransaction else { //
// guard let transaction = context.parentTransaction else {
CoreStore.log( //
.warning, // CoreStore.log(
message: "Attempted to change the \"\(key ?? "")\" of an object of type \(cs_typeName(self)) after has been deleted from its transaction." // .warning,
) // message: "Attempted to change the \"\(key ?? "")\" of an object of type \(cs_typeName(self)) after has been deleted from its transaction."
return // )
} // return
CoreStore.assert( // }
transaction.isRunningInAllowedQueue(), // CoreStore.assert(
"Attempted to change the \"\(key ?? "")\" of an object of type \(cs_typeName(self)) outside its transaction's designated queue." // transaction.isRunningInAllowedQueue(),
) // "Attempted to change the \"\(key ?? "")\" of an object of type \(cs_typeName(self)) outside its transaction's designated queue."
return // )
} // return
if context.isDataStackContext { // }
// if context.isDataStackContext {
guard context.parentStack != nil else { //
// guard context.parentStack != nil else {
CoreStore.log( //
.warning, // CoreStore.log(
message: "Attempted to change the \"\(key ?? "")\" of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(DataStack.self)).") // .warning,
return // message: "Attempted to change the \"\(key ?? "")\" of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(DataStack.self)).")
} // return
CoreStore.assert( // }
Thread.isMainThread, // CoreStore.assert(
"Attempted to change the \"\(key ?? "")\" of an object of type \(cs_typeName(self)) outside the main thread." // Thread.isMainThread,
) // "Attempted to change the \"\(key ?? "")\" of an object of type \(cs_typeName(self)) outside the main thread."
return // )
} // return
} // }
// }
private dynamic func cs_willChangeValue(forKey inKey: String, withSetMutation inMutationKind: NSKeyValueSetMutationKind, using inObjects: Set<AnyHashable>) { //
// private dynamic func cs_willChangeValue(forKey inKey: String, withSetMutation inMutationKind: NSKeyValueSetMutationKind, using inObjects: Set<AnyHashable>) {
self.cs_willChangeValue( //
forKey: inKey, // self.cs_willChangeValue(
withSetMutation: inMutationKind, // forKey: inKey,
using: inObjects // withSetMutation: inMutationKind,
) // using: inObjects
// )
guard CoreStore.logger.enableObjectConcurrencyDebugging else { //
// guard CoreStore.logger.enableObjectConcurrencyDebugging else {
return //
} // return
// }
guard let context = self.managedObjectContext else { //
// guard let context = self.managedObjectContext else {
CoreStore.log( //
.warning, // CoreStore.log(
message: "Attempted to mutate the \"\(inKey)\" of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(NSManagedObjectContext.self))." // .warning,
) // message: "Attempted to mutate the \"\(inKey)\" of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(NSManagedObjectContext.self))."
return // )
} // return
if context.isTransactionContext { // }
// if context.isTransactionContext {
guard let transaction = context.parentTransaction else { //
// guard let transaction = context.parentTransaction else {
CoreStore.log( //
.warning, // CoreStore.log(
message: "Attempted to mutate the \"\(inKey)\" of an object of type \(cs_typeName(self)) after has been deleted from its transaction." // .warning,
) // message: "Attempted to mutate the \"\(inKey)\" of an object of type \(cs_typeName(self)) after has been deleted from its transaction."
return // )
} // return
CoreStore.assert( // }
transaction.isRunningInAllowedQueue(), // CoreStore.assert(
"Attempted to mutate the \"\(inKey)\" of an object of type \(cs_typeName(self)) outside its transaction's designated queue." // transaction.isRunningInAllowedQueue(),
) // "Attempted to mutate the \"\(inKey)\" of an object of type \(cs_typeName(self)) outside its transaction's designated queue."
return // )
} // return
if context.isDataStackContext { // }
// if context.isDataStackContext {
guard context.parentStack != nil else { //
// guard context.parentStack != nil else {
CoreStore.log( //
.warning, // CoreStore.log(
message: "Attempted to mutate the \"\(inKey)\" of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(DataStack.self)).") // .warning,
return // message: "Attempted to mutate the \"\(inKey)\" of an object of type \(cs_typeName(self)) after has been deleted from its \(cs_typeName(DataStack.self)).")
} // return
CoreStore.assert( // }
Thread.isMainThread, // CoreStore.assert(
"Attempted to mutate the \"\(inKey)\" of an object of type \(cs_typeName(self)) outside the main thread." // Thread.isMainThread,
) // "Attempted to mutate the \"\(inKey)\" of an object of type \(cs_typeName(self)) outside the main thread."
return // )
} // return
} // }
// }
} }

View File

@@ -50,7 +50,8 @@ public protocol CoreStoreLogger {
/** /**
When `true`, all `NSManagedObject` attribute and relationship access will raise an assertion when executed on the wrong transaction/datastack queue. Defaults to `false` if not implemented. When `true`, all `NSManagedObject` attribute and relationship access will raise an assertion when executed on the wrong transaction/datastack queue. Defaults to `false` if not implemented.
*/ */
var enableObjectConcurrencyDebugging: Bool { get set } // TODO: test before release (rolled back)
// var enableObjectConcurrencyDebugging: Bool { get set }
/** /**
Handles log messages sent by the `CoreStore` framework. Handles log messages sent by the `CoreStore` framework.
@@ -99,11 +100,12 @@ public protocol CoreStoreLogger {
extension CoreStoreLogger { extension CoreStoreLogger {
public var enableObjectConcurrencyDebugging: Bool { // TODO: test before release (rolled back)
// public var enableObjectConcurrencyDebugging: Bool {
get { return false } //
set {} // get { return false }
} // set {}
// }
public func abort(_ message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) { public func abort(_ message: String, fileName: StaticString, lineNumber: Int, functionName: StaticString) {

View File

@@ -36,7 +36,8 @@ public final class DefaultLogger: CoreStoreLogger {
/** /**
When `true`, all `NSManagedObject` attribute and relationship access will raise an assertion when executed on the wrong transaction/datastack queue. Defaults to `false`. When `true`, all `NSManagedObject` attribute and relationship access will raise an assertion when executed on the wrong transaction/datastack queue. Defaults to `false`.
*/ */
public var enableObjectConcurrencyDebugging: Bool = false // TODO: test before release (rolled back)
// public var enableObjectConcurrencyDebugging: Bool = false
/** /**
Creates a `DefaultLogger`. Creates a `DefaultLogger`.

View File

@@ -58,8 +58,9 @@ public final class DataStack: Equatable {
- parameter migrationChain: the `MigrationChain` that indicates the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack. - parameter migrationChain: the `MigrationChain` that indicates the sequence of model versions to be used as the order for progressive migrations. If not specified, will default to a non-migrating data stack.
*/ */
public required init(model: NSManagedObjectModel, migrationChain: MigrationChain = nil) { public required init(model: NSManagedObjectModel, migrationChain: MigrationChain = nil) {
_ = DataStack.isGloballyInitialized // TODO: test before release (rolled back)
// _ = DataStack.isGloballyInitialized
CoreStore.assert( CoreStore.assert(
migrationChain.valid, migrationChain.valid,
@@ -501,11 +502,12 @@ public final class DataStack: Equatable {
// MARK: Private // MARK: Private
private static let isGloballyInitialized: Bool = { // TODO: test before release (rolled back)
// private static let isGloballyInitialized: Bool = {
NSManagedObject.cs_swizzleMethodsForLogging() //
return true // NSManagedObject.cs_swizzleMethodsForLogging()
}() // return true
// }()
private var configurationStoreMapping = [String: NSPersistentStore]() private var configurationStoreMapping = [String: NSPersistentStore]()
private var entityConfigurationsMapping = [String: Set<String>]() private var entityConfigurationsMapping = [String: Set<String>]()