Reduce leaking (a little) on the workaround for NSFetchRequest.affectedStores ARC bug

This commit is contained in:
John Estropia
2016-09-27 17:31:08 +09:00
parent 4d2ebe4ea8
commit ed8c7b35e8
8 changed files with 91 additions and 69 deletions

View File

@@ -576,6 +576,9 @@ CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CORESTORE_RE
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
NS_SWIFT_NAME(CoreStoreFetchRequest)
@interface _CSFetchRequest: NSFetchRequest
@property (nullable, nonatomic, copy, readonly) NSArray<NSPersistentStore *> *safeAffectedStores;
@end

View File

@@ -223,16 +223,35 @@ CSWhere *_Nonnull CSWherePredicate(NSPredicate *_Nonnull predicate) CORESTORE_RE
#pragma mark CoreStoreFetchRequest
@interface _CSFetchRequest ()
@property (nullable, nonatomic, copy) NSArray<NSPersistentStore *> *safeAffectedStores;
@property (nullable, nonatomic, assign) CFArrayRef releaseArray;
@end
@implementation _CSFetchRequest
- (NSArray<NSPersistentStore *> *)affectedStores {
// MARK: NSFetchRequest
- (void)setAffectedStores:(NSArray<NSPersistentStore *> *_Nullable)affectedStores {
// Bugfix for NSFetchRequest messing up memory management for `affectedStores`
// http://stackoverflow.com/questions/14396375/nsfetchedresultscontroller-crashes-in-ios-6-if-affectedstores-is-specified
CFBridgingRetain([super affectedStores]);
return [super affectedStores];
if (NSFoundationVersionNumber < NSFoundationVersionNumber10_0) {
self.safeAffectedStores = affectedStores;
[super setAffectedStores:affectedStores];
return;
}
if (self.releaseArray != NULL) {
CFRelease(self.releaseArray);
self.releaseArray = NULL;
}
self.safeAffectedStores = affectedStores;
[super setAffectedStores:affectedStores];
self.releaseArray = CFBridgingRetain([super affectedStores]);
}
@end

View File

@@ -1123,7 +1123,7 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
self.isPersistentStoreChanging = true
guard let removedStores = (note.userInfo?[NSRemovedPersistentStoresKey] as? [NSPersistentStore]).flatMap(Set.init)
where !Set(self.fetchedResultsController.fetchRequest.affectedStores ?? []).intersect(removedStores).isEmpty else {
where !Set((self.fetchedResultsController.fetchRequest as! CoreStoreFetchRequest).safeAffectedStores ?? []).intersect(removedStores).isEmpty else {
return
}
@@ -1144,7 +1144,7 @@ public final class ListMonitor<T: NSManagedObject>: Hashable {
if !self.isPendingRefetch {
let previousStores = Set(self.fetchedResultsController.fetchRequest.affectedStores ?? [])
let previousStores = Set((self.fetchedResultsController.fetchRequest as! CoreStoreFetchRequest).safeAffectedStores ?? [])
let currentStores = previousStores
.subtract(note.userInfo?[NSRemovedPersistentStoresKey] as? [NSPersistentStore] ?? [])
.union(note.userInfo?[NSAddedPersistentStoresKey] as? [NSPersistentStore] ?? [])