核心数据获取已删除对象

Posted

技术标签:

【中文标题】核心数据获取已删除对象【英文标题】:Core Data fetching deleted objects 【发布时间】:2014-10-30 15:24:23 【问题描述】:

我的问题的简短版本:我正在删除一个对象,并且在我执行返回之前删除的对象的 fetch 之后。

我正在关注这个架构: 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】:

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

我通过使用 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];

【讨论】:

以上是关于核心数据获取已删除对象的主要内容,如果未能解决你的问题,请参考以下文章

核心数据方便获取方法

核心数据:从多个 ManagedObjectContexts 中获取对象

ios核心数据未保存

核心数据获取请求中需要谓词?

从核心数据实体中删除对象/行

核心数据错误:文件仍未删除