Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Remove persistent store when closing document #5

Merged
merged 2 commits into from
Jun 2, 2019
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
80 changes: 52 additions & 28 deletions BSManagedDocument.m
Original file line number Diff line number Diff line change
Expand Up @@ -291,6 +291,9 @@ - (BOOL)updateMetadataForPersistentStore:(NSPersistentStore *)store error:(NSErr

- (void)close;
{
NSError *error = nil;
if (![self removePersistentStoreWithError:&error])
NSLog(@"Unable to remove persistent store before closing: %@", error);
[super close];
[self deleteAutosavedContentsTempDirectory];
}
Expand All @@ -312,6 +315,53 @@ - (void)dealloc;

#pragma mark Reading Document Data

- (BOOL)removePersistentStoreWithError:(NSError **)outError {
NSManagedObjectContext *context = self.managedObjectContext;
__block BOOL result = YES;
__block NSError * error = nil ;
if ([context respondsToSelector:@selector(parentContext)])
{
// In my testing, HAVE to do the removal using parent's private queue. Otherwise, it deadlocks, trying to acquire a _PFLock
NSManagedObjectContext *parent = context.parentContext;
while (parent)
{
context = parent; parent = context.parentContext;
}

[context performBlockAndWait:^{
result = [context.persistentStoreCoordinator removePersistentStore:_store error:&error];
#if !__has_feature(objc_arc)
[error retain];
#endif
}];
}
else
{
result = [context.persistentStoreCoordinator removePersistentStore:_store error:&error];
#if !__has_feature(objc_arc)
[error retain];
#endif
}

if (!result) {
#if !__has_feature(objc_arc)
[error autorelease];
#endif
if (outError) {
*outError = error;
}
return NO;
}

#if !__has_feature(objc_arc)
[_store release];
#endif

_store = nil;

return YES;
}

- (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError
{
// Preflight the URL
Expand All @@ -330,34 +380,8 @@ - (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSEr
// NSPersistentDocument states: "Revert resets the document’s managed object context. Objects are subsequently loaded from the persistent store on demand, as with opening a new document."
// I've found for atomic stores that -reset only rolls back to the last loaded or saved version of the store; NOT what's actually on disk
// To force it to re-read from disk, the only solution I've found is removing and re-adding the persistent store
NSManagedObjectContext *context = self.managedObjectContext;
if ([context respondsToSelector:@selector(parentContext)])
{
// In my testing, HAVE to do the removal using parent's private queue. Otherwise, it deadlocks, trying to acquire a _PFLock
NSManagedObjectContext *parent = context.parentContext;
while (parent)
{
context = parent; parent = context.parentContext;
}

__block BOOL result;
[context performBlockAndWait:^{
result = [context.persistentStoreCoordinator removePersistentStore:_store error:outError];
}];
}
else
{
if (![context.persistentStoreCoordinator removePersistentStore:_store error:outError])
{
return NO;
}
}

#if !__has_feature(objc_arc)
[_store release];
#endif

_store = nil;
if (![self removePersistentStoreWithError:outError])
return NO;
}


Expand Down