turns out inout arguments in closures are malloc nightmares. this finally fixes it

This commit is contained in:
John Estropia
2015-08-27 22:24:40 +09:00
parent ea6b6f2c37
commit d5e769be6c

View File

@@ -86,6 +86,8 @@ public extension BaseDataTransaction {
"Attempted to import an object of type \(typeName(into.entityClass)) outside the transaction's designated queue." "Attempted to import an object of type \(typeName(into.entityClass)) outside the transaction's designated queue."
) )
return try autoreleasepool {
guard T.shouldInsertFromImportSource(source, inTransaction: self) else { guard T.shouldInsertFromImportSource(source, inTransaction: self) else {
return nil return nil
@@ -95,6 +97,7 @@ public extension BaseDataTransaction {
try object.didInsertFromImportSource(source, inTransaction: self) try object.didInsertFromImportSource(source, inTransaction: self)
return object return object
} }
}
func importObjects<T where T: NSManagedObject, T: ImportableObject>( func importObjects<T where T: NSManagedObject, T: ImportableObject>(
into: Into<T>, into: Into<T>,
@@ -105,6 +108,8 @@ public extension BaseDataTransaction {
"Attempted to import an object of type \(typeName(into.entityClass)) outside the transaction's designated queue." "Attempted to import an object of type \(typeName(into.entityClass)) outside the transaction's designated queue."
) )
try autoreleasepool {
for source in sourceArray { for source in sourceArray {
guard T.shouldInsertFromImportSource(source, inTransaction: self) else { guard T.shouldInsertFromImportSource(source, inTransaction: self) else {
@@ -119,6 +124,7 @@ public extension BaseDataTransaction {
} }
} }
} }
}
func importObjects<T where T: NSManagedObject, T: ImportableObject>( func importObjects<T where T: NSManagedObject, T: ImportableObject>(
into: Into<T>, into: Into<T>,
@@ -130,6 +136,8 @@ public extension BaseDataTransaction {
"Attempted to import an object of type \(typeName(into.entityClass)) outside the transaction's designated queue." "Attempted to import an object of type \(typeName(into.entityClass)) outside the transaction's designated queue."
) )
try autoreleasepool {
var objects = [T]() var objects = [T]()
for source in sourceArray { for source in sourceArray {
@@ -148,6 +156,7 @@ public extension BaseDataTransaction {
} }
postProcess(sorted: objects) postProcess(sorted: objects)
} }
}
func importUniqueObject<T where T: NSManagedObject, T: ImportableUniqueObject>( func importUniqueObject<T where T: NSManagedObject, T: ImportableUniqueObject>(
into: Into<T>, into: Into<T>,
@@ -158,6 +167,8 @@ public extension BaseDataTransaction {
"Attempted to import an object of type \(typeName(into.entityClass)) outside the transaction's designated queue." "Attempted to import an object of type \(typeName(into.entityClass)) outside the transaction's designated queue."
) )
return try autoreleasepool {
let uniqueIDKeyPath = T.uniqueIDKeyPath let uniqueIDKeyPath = T.uniqueIDKeyPath
guard let uniqueIDValue = try T.uniqueIDFromImportSource(source, inTransaction: self) else { guard let uniqueIDValue = try T.uniqueIDFromImportSource(source, inTransaction: self) else {
@@ -182,17 +193,20 @@ public extension BaseDataTransaction {
return object return object
} }
} }
}
func importUniqueObjects<T where T: NSManagedObject, T: ImportableUniqueObject>( func importUniqueObjects<T where T: NSManagedObject, T: ImportableUniqueObject>(
into: Into<T>, into: Into<T>,
sourceArray: [T.ImportSource], sourceArray: [T.ImportSource],
preProcess: ((inout mapping: [T.UniqueIDType: T.ImportSource]) throws -> Void)? = nil) throws { preProcess: ((mapping: [T.UniqueIDType: T.ImportSource]) throws -> [T.UniqueIDType: T.ImportSource])? = nil) throws {
CoreStore.assert( CoreStore.assert(
self.bypassesQueueing || self.transactionQueue.isCurrentExecutionContext(), self.bypassesQueueing || self.transactionQueue.isCurrentExecutionContext(),
"Attempted to import an object of type \(typeName(into.entityClass)) outside the transaction's designated queue." "Attempted to import an object of type \(typeName(into.entityClass)) outside the transaction's designated queue."
) )
try autoreleasepool {
var mapping = Dictionary<T.UniqueIDType, T.ImportSource>() var mapping = Dictionary<T.UniqueIDType, T.ImportSource>()
for source in sourceArray { for source in sourceArray {
@@ -207,18 +221,15 @@ public extension BaseDataTransaction {
} }
} }
var mappingCopy = mapping // bugfix: prevent deallocation of exhausted items when accessed lazily with .keys and .values
if let preProcess = preProcess { if let preProcess = preProcess {
try autoreleasepool { try autoreleasepool {
try preProcess(mapping: &mappingCopy) mapping = try preProcess(mapping: mapping)
} }
} }
mapping = mappingCopy
var mappingCopyForKeys = mapping for object in self.fetchAll(From(T), Where(T.uniqueIDKeyPath, isMemberOf: mapping.keys)) ?? [] {
for object in self.fetchAll(From(T), Where(T.uniqueIDKeyPath, isMemberOf: mappingCopyForKeys.keys)) ?? [] {
try autoreleasepool { try autoreleasepool {
@@ -249,11 +260,12 @@ public extension BaseDataTransaction {
} }
} }
} }
}
func importUniqueObjects<T where T: NSManagedObject, T: ImportableUniqueObject>( func importUniqueObjects<T where T: NSManagedObject, T: ImportableUniqueObject>(
into: Into<T>, into: Into<T>,
sourceArray: [T.ImportSource], sourceArray: [T.ImportSource],
preProcess: ((inout mapping: [T.UniqueIDType: T.ImportSource]) throws -> Void)? = nil, preProcess: ((mapping: [T.UniqueIDType: T.ImportSource]) throws -> [T.UniqueIDType: T.ImportSource])? = nil,
postProcess: (sorted: [T]) -> Void) throws { postProcess: (sorted: [T]) -> Void) throws {
CoreStore.assert( CoreStore.assert(
@@ -261,6 +273,8 @@ public extension BaseDataTransaction {
"Attempted to import an object of type \(typeName(into.entityClass)) outside the transaction's designated queue." "Attempted to import an object of type \(typeName(into.entityClass)) outside the transaction's designated queue."
) )
try autoreleasepool {
var sortedIDs = Array<T.UniqueIDType>() var sortedIDs = Array<T.UniqueIDType>()
var mapping = Dictionary<T.UniqueIDType, T.ImportSource>() var mapping = Dictionary<T.UniqueIDType, T.ImportSource>()
for source in sourceArray { for source in sourceArray {
@@ -277,19 +291,16 @@ public extension BaseDataTransaction {
} }
} }
var mappingCopy = mapping // bugfix: prevent deallocation of exhausted items when accessed lazily with .keys and .values
if let preProcess = preProcess { if let preProcess = preProcess {
try autoreleasepool { try autoreleasepool {
try preProcess(mapping: &mappingCopy) mapping = try preProcess(mapping: mapping)
} }
} }
mapping = mappingCopy
var mappingCopyForKeys = mapping
var objects = Dictionary<T.UniqueIDType, T>() var objects = Dictionary<T.UniqueIDType, T>()
for object in self.fetchAll(From(T), Where(T.uniqueIDKeyPath, isMemberOf: mappingCopyForKeys.keys)) ?? [] { for object in self.fetchAll(From(T), Where(T.uniqueIDKeyPath, isMemberOf: mapping.keys)) ?? [] {
try autoreleasepool { try autoreleasepool {
@@ -326,3 +337,4 @@ public extension BaseDataTransaction {
postProcess(sorted: sortedIDs.flatMap { objects[$0] }) postProcess(sorted: sortedIDs.flatMap { objects[$0] })
} }
} }
}