如何处理persistentContainer加载失败的情况

问题描述

这是我用来为Core Data堆栈创建持久性容器的代码

当persistentContainer不是nil并且已经在CoredataHandler共享实例类中加载时,我想处理失败的情况。

CoredataHandler.h文件

@property (strong,nonatomic) NSPersistentContainer *persistentContainer;
@property (nonatomic) BOOL isstoreLoaded;

CoredataHandler.m文件

@implementation CoredataHandler

+(CoredataHandler *) sharedInstance
{
    static CoredataHandler *shared = nil;
    
    static dispatch_once_t oncetoken;
    
    dispatch_once(&oncetoken,^{
        
        shared = [[self alloc] init];
        
    });
    
    return shared;
}

- (id)init {
    if (self = [super init]) {
        _persistentContainer = self.persistentContainer;
    }
    return self;
}


@synthesize persistentContainer = _persistentContainer;

- (NSPersistentContainer *)persistentContainer {
    // The persistent container for the application. This implementation creates and returns a container,having loaded the store for the application to it.
    @synchronized (self) {
        NSURL * storeURL  =  [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
        storeURL = [storeURL URLByAppendingPathComponent:@"MyDataBase"];

        if (_persistentContainer == nil) {
            NSPersistentContainer *container = [[NSPersistentContainer alloc] initWithName:@"MyDataBase"];

            NSPersistentStoreDescription * persistentStoreDescription = [[NSPersistentStoreDescription alloc] initWithURL:storeURL];
            persistentStoreDescription.shouldMigrateStoreAutomatically = YES;
            [persistentStoreDescription setoption:NSFileProtectionComplete forKey:NSPersistentStoreFileProtectionKey];
            persistentStoreDescription.shouldInferMappingModelAutomatically = YES;
            container.persistentStoreDescriptions = @[persistentStoreDescription];

            [container loadPersistentStoresWithCompletionHandler:^(NSPersistentStoreDescription *storeDescription,NSError *error) {
                if (error != nil) {
                    // Replace this implementation with code to handle the error appropriately.
                    // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application,although it may be useful during development.

                    /*
                     Typical reasons for an error here include:
                     * The parent directory does not exist,cannot be created,or disallows writing.
                     * The persistent store is not accessible,due to permissions or data protection when the device is locked.
                     * The device is out of space.
                     * The store Could not be migrated to the current model version.
                     Check the error message to determine what the actual problem was.
                     */
                    NSLog(@"Unresolved error %@,%@",error,error.userInfo);
                    //abort();

                    self->_isstoreLoaded = NO;

                }
                self->_isstoreLoaded = YES;
                return;

            }];

            if (self.isstoreLoaded) {
                _persistentContainer = container;
            }
        }  else {
            if (![self persistentStoreExistsWithStoreURL:storeURL]) {
                _persistentContainer = nil;
            }
        }
    }
    return _persistentContainer;

}

我通过检查商店是否在路径中进行了尝试

-(BOOL)persistentStoreExistsWithStoreURL:(NSURL *)url {

    if (url &&
        url.isFileURL &&
        [NSFileManager.defaultManager fileExistsAtPath:url.path]) {
        return YES;
    }
    return NO;
}


-(NSBatchUpdateResult *)executeRequestForNSBatchUpdateResult:(NSBatchUpdateRequest *)updateRequest {
    NSBatchUpdateResult *batchUpdateResult = nil;
    if (!self.persistentContainer) {
        return nil;
    }

    if (self.persistentContainer.viewContext) {
        batchUpdateResult = (NSBatchUpdateResult *)[self.persistentContainer.viewContext executeRequest:updateRequest error:nil];
    }
    return batchUpdateResult;
}


@end

-(void)markItmesInCategory:(NSNumber*)categoryId {
    NSBatchUpdateRequest *req= [[NSBatchUpdateRequest alloc] initWithEntityName:@"Items_table"];
    req.predicate = [nspredicate predicateWithFormat:@"categoryId=%d",[channelKey intValue]];
    req.propertiesToUpdate = @{
        @"status" : @(1)
    };
    req.resultType = NSUpdatedobjectsCountResultType;
    CoredataHandler * dbHandler = [CoredataHandler sharedInstance];

    NSError * fetchError = nil;

    NSBatchUpdateResult *batchUpdateResult = (NSBatchUpdateResult *)[dbHandler executeRequestForNSBatchUpdateResult:req];

    if (batchUpdateResult) {
        NSLog(@"updated rows",batchUpdateResult.result);
    }
}

如果在共享实例类中已加载对象,并且存储在访问时存在某些权限问题,该如何处理?

示例: 锁定设备后,由于权限或数据保护,无法访问持久性存储。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)