mirror of
https://github.com/zhigang1992/MagicalRecord.git
synced 2026-01-12 17:32:18 +08:00
some changes to the background saving api…
getting things to compile for the time being
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -18,7 +18,6 @@
|
||||
|
||||
+ (void) cleanUp
|
||||
{
|
||||
cleanup_save_queue();
|
||||
[self cleanUpErrorHanding];
|
||||
[self cleanUpStack];
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user