some changes to the background saving api…

getting things to compile for the time being
This commit is contained in:
Saul Mora
2012-03-09 17:40:19 +01:00
parent c9c8d2473a
commit e11f2e67b0
8 changed files with 138 additions and 131 deletions

View File

@@ -13,8 +13,10 @@ extern NSString * const kMagicalRecordDidMergeChangesFromiCloudNotification;
+ (void) MR_initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinator *)coordinator;
+ (NSManagedObjectContext *) MR_context;
+ (NSManagedObjectContext *) MR_contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator;
+ (NSManagedObjectContext *) MR_context NS_RETURNS_RETAINED;
+ (NSManagedObjectContext *) MR_newMainQueueContext NS_RETURNS_RETAINED;
+ (NSManagedObjectContext *) MR_contextThatPushesChangesToDefaultContext NS_RETURNS_RETAINED;
+ (NSManagedObjectContext *) MR_contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator NS_RETURNS_RETAINED;
+ (void) MR_resetDefaultContext;
+ (NSManagedObjectContext *) MR_defaultContext;

View File

@@ -21,7 +21,7 @@ static NSManagedObjectContext *defaultManageObjectContext_ = nil;
@implementation NSManagedObjectContext (MagicalRecord)
+ (NSManagedObjectContext *)MR_defaultContext
+ (NSManagedObjectContext *) MR_defaultContext
{
@synchronized (self)
{
@@ -29,7 +29,7 @@ static NSManagedObjectContext *defaultManageObjectContext_ = nil;
}
}
+ (void)MR_setDefaultContext:(NSManagedObjectContext *)moc
+ (void) MR_setDefaultContext:(NSManagedObjectContext *)moc
{
NSPersistentStoreCoordinator *coordinator = [NSPersistentStoreCoordinator MR_defaultStoreCoordinator];
if ([MagicalRecord isICloudEnabled])
@@ -45,7 +45,21 @@ static NSManagedObjectContext *defaultManageObjectContext_ = nil;
}
}
+ (void)MR_resetDefaultContext
+ (void) MR_initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinator *)coordinator;
{
if ([self MR_defaultContext] == nil)
{
NSManagedObjectContext *context = [self MR_context];
[context performBlockAndWait:^{
[context setPersistentStoreCoordinator:coordinator];
}];
[self MR_setDefaultContext:context];
}
}
+ (void) MR_resetDefaultContext
{
void (^resetBlock)(void) = ^{
[[NSManagedObjectContext MR_defaultContext] reset];
@@ -60,18 +74,18 @@ static NSManagedObjectContext *defaultManageObjectContext_ = nil;
return context;
}
+ (void) MR_initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinator *)coordinator;
+ (NSManagedObjectContext *) MR_newMainQueueContext;
{
if ([self MR_defaultContext] == nil)
{
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
NSManagedObjectContext *context = [[self alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
return context;
}
[context performBlockAndWait:^{
[context setPersistentStoreCoordinator:coordinator];
}];
[self MR_setDefaultContext:context];
}
+ (NSManagedObjectContext *) MR_contextThatPushesChangesToDefaultContext;
{
NSManagedObjectContext *context = [self MR_defaultContext];
NSManagedObjectContext *childContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[childContext setParentContext:context];
return childContext;
}
+ (NSManagedObjectContext *) MR_contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator;

View File

@@ -10,14 +10,13 @@
@interface NSManagedObjectContext (MagicalSaves)
- (BOOL) MR_save;
- (void) MR_save;
- (void) MR_saveErrorHandler:(void (^)(NSError *))errorCallback;
#ifdef NS_BLOCKS_AVAILABLE
- (BOOL) MR_saveWithErrorHandler:(void (^)(NSError *))errorCallback;
#endif
- (BOOL) MR_saveOnMainThread;
- (BOOL) MR_saveOnBackgroundThread;
- (void) MR_saveInBackground;
- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *))errorCallback;
- (void) MR_saveNestedContexts;
- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback;
@end

View File

@@ -8,74 +8,80 @@
#import "NSManagedObjectContext+MagicalSaves.h"
@interface NSManagedObjectContext (InternalMagicalSaves)
- (void) MR_saveErrorCallback:(void(^)(NSError *))errorCallback;
@end
@implementation NSManagedObjectContext (MagicalSaves)
- (BOOL) MR_saveNestedContexts:(BOOL)saveParents errorHandler:(void(^)(NSError *))errorCallback;
- (void) MR_saveErrorCallback:(void(^)(NSError *))errorCallback;
{
__block NSError *error = nil;
__block BOOL saved = NO;
MRLog(@"Saving %@Context%@", self == [[self class] MR_defaultContext] ? @" *** Default *** ": @"", ([NSThread isMainThread] ? @" *** on Main Thread ***" : @""));
NSError *error = nil;
BOOL saved = NO;
@try
{
[self performBlockAndWait:^{
MRLog(@"Saving %@Context%@",
self == [[self class] MR_defaultContext] ? @" *** Default *** ": @"",
([NSThread isMainThread] ? @" *** on Main Thread ***" : @""));
saved = [self save:&error];
}];
saved = [self save:&error];
}
@catch (NSException *exception)
{
MRLog(@"Problem saving: %@", (id)[exception userInfo] ?: (id)[exception reason]);
MRLog(@"Unable to perform save: %@", (id)[exception userInfo] ?: (id)[exception reason]);
}
@finally
{
NSManagedObjectContext *parentContext = [self parentContext];
if (saved && saveParents)
{
return saved && [parentContext MR_saveNestedContexts:saveParents errorHandler:errorCallback];
}
if (!saved)
{
[MagicalRecord handleErrors:error];
if (errorCallback)
{
errorCallback(error);
}
else
{
[MagicalRecord handleErrors:error];
}
}
return saved;
}
}
- (BOOL) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback;
- (void) MR_saveNestedContexts;
{
return [self MR_saveNestedContexts:YES errorHandler:errorCallback];
[self MR_saveNestedContextsErrorHandler:nil];
}
- (BOOL) MR_saveWithErrorHandler:(void (^)(NSError *))errorCallback;
- (void) MR_saveNestedContextsErrorHandler:(void (^)(NSError *))errorCallback;
{
return [self MR_saveNestedContexts:NO errorHandler:errorCallback];
[self performBlockAndWait:^{
[self MR_saveErrorCallback:errorCallback];
}];
[[self parentContext] MR_saveNestedContextsErrorHandler:errorCallback];
}
- (BOOL) MR_save;
- (void) MR_save;
{
return [self MR_saveNestedContexts:NO errorHandler:nil];
[self MR_saveErrorCallback:nil];
}
#pragma mark - Threading Save Helpers
- (BOOL) MR_saveOnBackgroundThread;
- (void) MR_saveErrorHandler:(void (^)(NSError *))errorCallback;
{
[self performSelectorInBackground:@selector(MR_save) withObject:nil];
return YES;
[self performBlockAndWait:^{
[self MR_saveErrorCallback:errorCallback];
}];
}
- (BOOL) MR_saveOnMainThread;
- (void) MR_saveInBackground;
{
@synchronized(self)
{
[self performSelectorOnMainThread:@selector(MR_save) withObject:nil waitUntilDone:YES];
}
return YES;
[self MR_saveInBackgroundErrorHandler:nil];
}
- (void) MR_saveInBackgroundErrorHandler:(void (^)(NSError *))errorCallback;
{
[self performBlock:^{
[self MR_saveErrorCallback:errorCallback];
}];
}
@end

View File

@@ -24,6 +24,11 @@
#define MRLog(...) ((void)0)
#endif
#ifndef NS_BLOCKS_AVAILABLE
#warning MagicalRecord requires blocks
#endif
// #if !( __has_feature(objc_arc) && __has_feature(objc_arc_weak) )
// #error MagicalRecord now requires ARC to be enabled
// #endif

View File

@@ -11,15 +11,9 @@
@interface MagicalRecord (Actions)
#ifdef NS_BLOCKS_AVAILABLE
+ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block;
+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block;
+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(void(^)(void))callback;
#endif
@end
void cleanup_save_queue();
@end

View File

@@ -8,50 +8,17 @@
#import "CoreData+MagicalRecord.h"
#import "NSManagedObjectContext+MagicalRecord.h"
#import <dispatch/dispatch.h>
dispatch_queue_t background_save_queue(void);
void cleanup_save_queue(void);
static dispatch_queue_t coredata_background_save_queue;
dispatch_queue_t background_save_queue()
{
if (coredata_background_save_queue == NULL)
{
coredata_background_save_queue = dispatch_queue_create("com.magicalpanda.magicalrecord.backgroundsaves", 0);
}
return coredata_background_save_queue;
}
void cleanup_save_queue()
{
if (coredata_background_save_queue != NULL)
{
dispatch_release(coredata_background_save_queue);
coredata_background_save_queue = NULL;
}
}
@implementation MagicalRecord (Actions)
#ifdef NS_BLOCKS_AVAILABLE
+ (void) saveWithBlock:(void (^)(NSManagedObjectContext *localContext))block errorHandler:(void (^)(NSError *))errorHandler
+ (void) saveInBackgroundWithBlock:(void (^)(NSManagedObjectContext *))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *))errorHandler;
{
NSManagedObjectContext *mainContext = [NSManagedObjectContext MR_defaultContext];
NSManagedObjectContext *localContext = mainContext;
NSPersistentStoreCoordinator *defaultCoordinator = [NSPersistentStoreCoordinator MR_defaultStoreCoordinator];
if (![NSThread isMainThread])
{
#if kCreateNewCoordinatorOnBackgroundOperations == 1
NSPersistentStoreCoordinator *localCoordinator = [NSPersistentStoreCoordinator coordinatorWithPersitentStore:[NSPersistentStore defaultPersistentStore]];
localContext = [NSManagedObjectContext contextThatNotifiesDefaultContextOnMainThreadWithCoordinator:localCoordinator];
#else
localContext = [NSManagedObjectContext MR_contextForCurrentThread];
[localContext MR_observeiCloudChangesInCoordinator:defaultCoordinator];
#endif
localContext = [NSManagedObjectContext MR_contextThatPushesChangesToDefaultContext];
[mainContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
[localContext setMergePolicy:NSOverwriteMergePolicy];
}
@@ -60,49 +27,70 @@ void cleanup_save_queue()
if ([localContext hasChanges])
{
[localContext MR_saveWithErrorHandler:errorHandler];
[localContext MR_saveInBackgroundErrorHandler:errorHandler];
}
[localContext MR_stopObservingiCloudChangesInCoordinator:defaultCoordinator];
[mainContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
if (completion)
{
completion();
}
}
+ (void) saveWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))completion errorHandler:(void (^)(NSError *))errorHandler;
{
NSManagedObjectContext *mainContext = [NSManagedObjectContext MR_defaultContext];
NSManagedObjectContext *localContext = mainContext;
if (![NSThread isMainThread])
{
localContext = [NSManagedObjectContext MR_contextThatPushesChangesToDefaultContext];
[mainContext setMergePolicy:NSMergeByPropertyStoreTrumpMergePolicy];
[localContext setMergePolicy:NSOverwriteMergePolicy];
}
block(localContext);
if ([localContext hasChanges])
{
[localContext MR_saveErrorHandler:errorHandler];
}
[mainContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
if (completion)
{
completion();
}
}
+ (void) saveWithBlock:(void(^)(NSManagedObjectContext *localContext))block
{
[self saveWithBlock:block errorHandler:NULL];
[self saveWithBlock:block completion:nil errorHandler:nil];
}
+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block
{
dispatch_async(background_save_queue(), ^{
[self saveWithBlock:block];
});
[self saveInBackgroundWithBlock:block completion:nil errorHandler:nil];
}
+ (void) saveInBackgroundWithBlock:(void(^)(NSManagedObjectContext *localContext))block completion:(void(^)(void))callback
{
dispatch_async(background_save_queue(), ^{
[self saveWithBlock:block];
if (callback)
{
dispatch_async(dispatch_get_main_queue(), callback);
}
});
[self saveInBackgroundWithBlock:block completion:callback errorHandler:nil];
}
+ (void) saveInBackgroundWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))callback errorHandler:(void (^)(NSError *))errorHandler
{
dispatch_async(background_save_queue(), ^{
[self saveWithBlock:block errorHandler:errorHandler];
if (callback)
{
dispatch_async(dispatch_get_main_queue(), callback);
}
});
}
#endif
//
//+ (void) saveInBackgroundWithBlock:(void (^)(NSManagedObjectContext *localContext))block completion:(void (^)(void))callback errorHandler:(void (^)(NSError *))errorHandler
//{
// dispatch_async(background_save_queue(), ^{
// [self saveWithBlock:block errorHandler:errorHandler];
//
// if (callback)
// {
// dispatch_async(dispatch_get_main_queue(), callback);
// }
// });
//}
@end

View File

@@ -18,7 +18,6 @@
+ (void) cleanUp
{
cleanup_save_queue();
[self cleanUpErrorHanding];
[self cleanUpStack];
}