核心数据获取已删除的对象

时间:2014-10-30 15:24:24

标签: ios objective-c core-data nsmanagedobjectcontext

我的问题的简短版本:我正在删除一个对象,然后我执行一个返回先前删除的对象的提取。

我正在遵循这个架构: SyncService - >持久性服务 - > NSManagedObject

Persistence Service层中的所有类都是以下类的子类:

# PersistenceService.h
#import <Foundation/Foundation.h>

@interface PersistenceService : NSObject

@property (nonatomic, retain) NSManagedObjectContext *context;

-(instancetype) init;
-(void) saveContext;
@end

# PersistenceService.m
@implementation PersistenceService

-(instancetype) init {
    self = [super init];

    if (self) {
        self.context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        self.context.parentContext = [DataManager sharedInstance].managedObjectContext;
    }

    return self;
}

-(void) saveContext {
    NSManagedObjectContext *context = self.context.parentContext;

    [self.context performBlock:^{

        NSError *error;
        [self.context save:&error];

        [context performBlock:^{
            NSError *error;
            [context save:&error];

            [context.parentContext performBlock:^{
                NSError *error;
                [context.parentContext save:&error];

            }];
        }];
    }];

}

@end

在删除之前,我在主要上下文中获取对象:

# Synchronizer.m
-(void) synchronize {
    NSArray *pseudoLeads = [[[PseudoLeadPersistenceService alloc] init] getAllParentPseudoLeads];
    if (pseudoLeads) {
        PseudoLeadDAO *pseudoLead = [pseudoLeads objectAtIndex:0];
        if ([pseudoLead.type isEqualToNumber:[NSNumber numberWithInt:Capture]]) {
            CaptureSyncService *service = [[CaptureSyncService alloc] initWithDelegate:self andPseudoLead:pseudoLead];
            [service executeRequest];
        } else {
            HotleadSyncService *service = [[HotleadSyncService alloc] initWithDelegate:self andPseudoLead:pseudoLead];
            [service executeRequest];
        }
    }
}

# PseudoLeadPersistenceService.m
-(NSArray *) getAllParentPseudoLeads {
    return [PseudoLeadDAO findAllParentPseudoLeadsInContext:self.context.parentContext];
}

在这里我获取并实际删除了我的子上下文中的对象:

# PseudoLeadPersistenceService.m
-(void) deletePseudoLeadById:(NSNumber *)pseudoLeadId andEventId:(NSNumber *)eventId {
    PseudoLeadDAO *pseudoLeadDAO = [PseudoLeadDAO findPseudoLeadById:pseudoLeadId andEventId:eventId inContext:self.context];
    [self.context deleteObject:pseudoLeadDAO];
    [self saveContext];
}

然后再次调用-(void) synchronize,删除的对象再次显示为错误。此时,我可以根据需要获取多次,它将被返回。它只会在-(void) deletePseudoLeadById:(NSNumber *)pseudoLeadId andEventId:(NSNumber *)eventId方法再次消失时才会消失。

我会感激任何帮助。谢谢!

1 个答案:

答案 0 :(得分:0)

问题是并发性。在下次获取之前,线程开始保存上下文没有完成。

我通过使用performBlockAndWait解决了这个问题:

# PersistenceService.m
-(void) saveContextAndWait {
    NSManagedObjectContext *context = self.context.parentContext;

    [self.context performBlockAndWait:^{

        NSError *error;
        [self.context save:&error];

        [context performBlockAndWait:^{
            NSError *error;
            [context save:&error];

            [context.parentContext performBlockAndWait:^{
                NSError *error;
                [context.parentContext save:&error];

            }];
        }];
    }];
}

# PseudoLeadPersistenceService.m
-(void) deletePseudoLeadById:(NSNumber *)pseudoLeadId andEventId:(NSNumber *)eventId {
    PseudoLeadDAO *pseudoLeadDAO = [PseudoLeadDAO findPseudoLeadById:pseudoLeadId andEventId:eventId inContext:self.context];
    [self.context deleteObject:pseudoLeadDAO];
    [self saveContextAndWait];
}