Iphone 启动后,在后台删除不起作用
我正在尝试创建一些方法,使在后台执行核心数据变得更容易。我正在做的是:Iphone 启动后,在后台删除不起作用,iphone,ios,core-data,nsfetchedresultscontroller,grand-central-dispatch,Iphone,Ios,Core Data,Nsfetchedresultscontroller,Grand Central Dispatch,我正在尝试创建一些方法,使在后台执行核心数据变得更容易。我正在做的是: 使用NSOperationQueue的-addOperationWithBlock:创建后台线程 在后台线程中,使用与主线程上的上下文相同的persistentStoreCoordinator创建一个NSManagedObjectContext,并将undoManager设置为nil 将观察者添加到默认通知中心,以侦听NSManagedObjectContextDidSaveNotification通知,并按如下方式处理它
- 使用
的NSOperationQueue
创建后台线程-addOperationWithBlock:
- 在后台线程中,使用与主线程上的上下文相同的
创建一个persistentStoreCoordinator
,并将NSManagedObjectContext
设置为undoManager
nil
- 将观察者添加到默认通知中心,以侦听
通知,并按如下方式处理它们:NSManagedObjectContextDidSaveNotification
- (void)mergeChanges:(NSNotification *)notification { dispatch_sync(dispatch_get_main_queue(), ^{ [_mainContext mergeChangesFromContextDidSaveNotification:notification]; }); }
FJCoreDataHelper *helper = [[FJCoreDataHelper alloc] initUsingMainManagedObjectContext:[self mainContext]]; [helper performBlockInBackground:^(NSManagedObjectContext *backgroundContext) { // [Fetch objets here...] // Delete: const int kSaveThreshold = 50; for (int card = 0, count = [allCards count]; card < count; card++) { [backgroundContext deleteObject:[allCards objectAtIndex:card]]; if (card % kSaveThreshold == 0) { [helper saveBackgroundContext]; } } }];
- 执行一个传入的块,它执行所有核心数据。它会定期在后台上下文中调用
save:
- 完成所有操作后,将观察员从通知中心移除
NSFetchedResultsController
显示数据。控制器的缓存设置为nil
有没有关于如何解决这个问题的建议
这是相关代码。请注意,我使用的是ARC
FJCoreDataBackgroundBlock
的定义如下:
typedef void(^FJCoreDataBackgroundBlock)(NSManagedObjectContext *backgroundContext);
在后台执行一堆核心数据的方法
- (void)performBlockInBackground:(FJCoreDataBackgroundBlock)block
{
[FJSharedOperationQueue addOperationWithBlock:^{
self.managedObjectContext = [[NSManagedObjectContext alloc] init];
[_managedObjectContext setUndoManager:nil];
[_managedObjectContext setPersistentStoreCoordinator:self.persistentStoreCoordinator];
[self setupNotificationCenterObserverForContext:_managedObjectContext];
FJCoreDataBackgroundBlock backgroundBlock = [block copy];
backgroundBlock(self.managedObjectContext);
[self saveBackgroundContext];
[self saveMainContext];
[self removeNotificationCenterObserver];
}];
}
FJSharedOperationQueue
的实现:
+ (NSOperationQueue *)sharedQueue
{
static dispatch_once_t predicate = 0;
__strong static NSOperationQueue *_sharedQueue = nil;
dispatch_once(&predicate, ^{
_sharedQueue = [[NSOperationQueue alloc] init];
[_sharedQueue setMaxConcurrentOperationCount:1];
});
return _sharedQueue;
}
+ (void)addOperationWithBlock:(void (^)(void))block
{
[[FJSharedOperationQueue sharedQueue] addOperationWithBlock:block];
}
现在这很奇怪:我在删除对象的块中的代码行中来回移动。在它看起来像这样之前:
- (void)mergeChanges:(NSNotification *)notification
{
dispatch_sync(dispatch_get_main_queue(), ^{
[_mainContext mergeChangesFromContextDidSaveNotification:notification];
});
}
FJCoreDataHelper *helper = [[FJCoreDataHelper alloc] initUsingMainManagedObjectContext:[self mainContext]];
[helper performBlockInBackground:^(NSManagedObjectContext *backgroundContext) {
// [Fetch objets here...]
// Delete:
const int kSaveThreshold = 50;
for (int card = 0, count = [allCards count]; card < count; card++)
{
[backgroundContext deleteObject:[allCards objectAtIndex:card]];
if (card % kSaveThreshold == 0)
{
[helper saveBackgroundContext];
}
}
}];
FJCoreDataHelper*helper=[[FJCoreDataHelper alloc]initUsingMainManagedObjectContext:[self-mainContext]];
[helper performBlockInBackground:^(NSManagedObjectContext*backgroundContext){
//[在这里取对象…]
//删除:
const int ksavestreshold=50;
对于(int card=0,count=[allCards count];card
要修复它,我只需在保存背景上下文后保存主上下文:
[helper performBlockInBackground:^(NSManagedObjectContext *backgroundContext) {
// [Fetch objets here...]
// Delete:
const int kSaveThreshold = 50;
for (int card = 0, count = [allCards count]; card < count; card++)
{
[backgroundContext deleteObject:[allCards objectAtIndex:card]];
if (card % kSaveThreshold == 0)
{
[helper saveBackgroundContext];
[helper saveMainContext];
}
}
}];
[helper performBlockInBackground:^(NSManagedObjectContext*backgroundContext){
//[在这里取对象…]
//删除:
const int ksavestreshold=50;
对于(int card=0,count=[allCards count];card
如果我只保存背景上下文,它就会崩溃。如果我先保存主上下文,它也会崩溃。我觉得这很奇怪,因为我认为将背景上下文合并到主上下文中也可以保存主上下文