mirror of
https://github.com/zhigang1992/MagicalRecord.git
synced 2026-04-30 21:12:46 +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;
|
+ (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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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();
|
|
||||||
@@ -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
|
||||||
@@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
+ (void) cleanUp
|
+ (void) cleanUp
|
||||||
{
|
{
|
||||||
cleanup_save_queue();
|
|
||||||
[self cleanUpErrorHanding];
|
[self cleanUpErrorHanding];
|
||||||
[self cleanUpStack];
|
[self cleanUpStack];
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user