未在核心数据中保存子上下文
问题描述:
我正在使用子上下文来保存核心数据对象,但根本没有保存。代码有什么问题? 我尝试通过删除执行块并使用performblockAndwait以及但不工作。像prepareDataForCustomYearlyOption方法一样,我还有其他三种方法,每天,每周和每月使用几乎相同的代码。未在核心数据中保存子上下文
另一个地方相同的代码工作。
- (NSManagedObjectContext *)backgroundManagedObjectContext
{
if (_managedObjectContext == nil) {
[[OUCSCoreDataManager privateInstance]managedObjectContext];
}
NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
temporaryContext.parentContext = _managedObjectContext;
return temporaryContext;
}
- (void)prepareDataForCustomYearlyOption {
if ([CoreDataManager countForEntity:kCALENDAR_CUSTOM_YEARLY_REPEAT_OPTIONS] != 0) {
return;
}
NSManagedObjectContext *temporaryContext = [[CoreDataManager privateInstance]backgroundManagedObjectContext];
[temporaryContext performBlock:^{
@try {
RepeatOptionsCustomYearly *yearlyOption = [RepeatOptionsCustomYearly insertInManagedObjectContext:temporaryContext];
yearlyOption.title = NSLocalizedString(k_Yearly, @"REPEAT_OPTIONS_TITILE3");
yearlyOption.isSelected = [NSNumber numberWithBool:NO];
yearlyOption.every = [NSNumber numberWithInt:1];
yearlyOption.startOn = [NSDate date];
yearlyOption.endsOn = [NSDate date];
yearlyOption.neverEnds = [NSNumber numberWithBool:NO];
yearlyOption.summary = @"";
yearlyOption.everyRange = [NSKeyedArchiver archivedDataWithRootObject:[self getYearRange]];
} @catch (NSException *exception) {
NSLog(@"Calendar Manager Exception: --> %@ %@",exception.name, exception.reason);
}
// push to parent
[temporaryContext performBlock:^{
// push to parent
NSError *errorTemp;
if (![temporaryContext save:&errorTemp])
{
// handle error
NSLog(@"Temp MOC Save Error: %@",errorTemp.description);
}
}];
}];
}
答
我想你的代码包含两个问题。第一个是backgroundManagedObjectContext
方法。 伊娃_managedObjectContext
从未设置:
- (NSManagedObjectContext *)backgroundManagedObjectContext
{
if (_managedObjectContext == nil) {
_managedObjectContext = [[OUCSCoreDataManager privateInstance]managedObjectContext];
}
NSManagedObjectContext *temporaryContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
temporaryContext.parentContext = _managedObjectContext;
return temporaryContext;
}
第二个可能是你叫两次performBlock
:
- (void)prepareDataForCustomYearlyOption {
if ([CoreDataManager countForEntity:kCALENDAR_CUSTOM_YEARLY_REPEAT_OPTIONS] != 0) {
return;
}
NSManagedObjectContext *temporaryContext = [[CoreDataManager privateInstance]backgroundManagedObjectContext];
[temporaryContext performBlock:^{
@try {
RepeatOptionsCustomYearly *yearlyOption = [RepeatOptionsCustomYearly insertInManagedObjectContext:temporaryContext];
yearlyOption.title = NSLocalizedString(k_Yearly, @"REPEAT_OPTIONS_TITILE3");
yearlyOption.isSelected = [NSNumber numberWithBool:NO];
yearlyOption.every = [NSNumber numberWithInt:1];
yearlyOption.startOn = [NSDate date];
yearlyOption.endsOn = [NSDate date];
yearlyOption.neverEnds = [NSNumber numberWithBool:NO];
yearlyOption.summary = @"";
yearlyOption.everyRange = [NSKeyedArchiver archivedDataWithRootObject:[self getYearRange]];
} @catch (NSException *exception) {
NSLog(@"Calendar Manager Exception: --> %@ %@",exception.name, exception.reason);
}
// push to parent
// Comment this ->[temporaryContext performBlock:^{
// push to parent
NSError *errorTemp;
if (![temporaryContext save:&errorTemp])
{
// handle error
NSLog(@"Temp MOC Save Error: %@",errorTemp.description);
}
// Comment this -> }];
}];
}
不要忘记,如果需要将其保存在temporaryContext
父上下文。
答
你可以尝试这样的事情,但错误处理是不遵循一个例子:
确保您得到您的私人队列正确设置与主要内容。
func getPrivateQueueMOC() -> NSManagedObjectContext?
{
if let moc = delegate.managedObjectContext
{
let privateMOC = NSManagedObjectContext(concurrencyType: NSManagedObjectContextConcurrencyType.privateQueueConcurrencyType)
privateMOC.parent = moc
return privateMOC
}
return nil
}
这可以确保您保存更改并尽快
func savePrivateContext(privateContext:NSManagedObjectContext)
{
do {
try privateContext.save()
guard let moc = delegate.managedObjectContext else { return }
moc.performAndWait {
do {
try moc.save()
} catch {
fatalError("Failure to save context: \(error)")
}
}
} catch {
fatalError("Failure to save context: \(error)")
}
}
更新主上下文中使用的专用队列
func persistStuff(_ stuff:[Dictionary<String, AnyObject>])
{
if stuff.isEmpty
{
return
}
if let context = getPrivateQueueMOC()
{
context.perform({() -> Void in
// Do your stuff here
if context.hasChanges
{
self.savePrivateContext(privateContext: context)
}
DispatchQueue.main.async(execute: {() -> Void in
// Tell UI to update
})
})
}
}
_managedObjectContext是有正确的方法,它是初始化。我试图删除执行块,但它不工作。 – Sandy
保存操作过程中是否有错误? – yageek