未在核心数据中保存子上下文

问题描述:

我正在使用子上下文来保存核心数据对象,但根本没有保存。代码有什么问题? 我尝试通过删除执行块并使用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父上下文。

+0

_managedObjectContext是有正确的方法,它是初始化。我试图删除执行块,但它不工作。 – Sandy

+0

保存操作过程中是否有错误? – yageek

你可以尝试这样的事情,但错误处理是不遵循一个例子:

确保您得到您的私人队列正确设置与主要内容。

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 
      }) 
     }) 
    } 
}