2017-01-23 10 views
0

コアデータオブジェクトを保存するために子コンテキストを使用していますが、保存しません。コードの問題は何ですか? 私はperformブロックを削除し、performblockAndwaitも使用しましたが、動作しませんでした。 prepareDataForCustomYearlyOptionメソッドと同様に、私は他のメソッドを毎日、毎週、毎月、以下のコードと同じコードで3つ持っています。子コンテキストがコアデータに保存されない

別の場所でも同じコードが動作しています。

- (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); 
      } 
     }]; 

    }]; 
} 

答えて

0

あなたのコードには2つの問題があると思います。

最初のものはbackgroundManagedObjectContextメソッドの内側です。 IVAR _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

1

あなたはこのような何かを試すことができますが、エラー処理が従うべき例ではない:

はあなたのプライベートキューは、メインコンテキストに正しく設定され得ることを確認。

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 
      }) 
     }) 
    } 
} 
関連する問題