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; + (void) MR_initializeDefaultContextWithCoordinator:(NSPersistentStoreCoordinator *)coordinator;
+ (NSManagedObjectContext *) MR_context; + (NSManagedObjectContext *) MR_context NS_RETURNS_RETAINED;
+ (NSManagedObjectContext *) MR_contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator; + (NSManagedObjectContext *) MR_newMainQueueContext NS_RETURNS_RETAINED;
+ (NSManagedObjectContext *) MR_contextThatPushesChangesToDefaultContext NS_RETURNS_RETAINED;
+ (NSManagedObjectContext *) MR_contextWithStoreCoordinator:(NSPersistentStoreCoordinator *)coordinator NS_RETURNS_RETAINED;
+ (void) MR_resetDefaultContext; + (void) MR_resetDefaultContext;
+ (NSManagedObjectContext *) MR_defaultContext; + (NSManagedObjectContext *) MR_defaultContext;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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