简体   繁体   English

合并托管对象上下文后,托管对象属性变为零

[英]managed object property becomes nil after merging managed object contexts

I have a managed object named SpecialItem and call setSubcategory to change the subcategory. 我有一个名为SpecialItem的托管对象,并调用setSubcategory来更改子类别。 When I save the temporary context and merge with the main context, somehow setSubcategory is called passing in nil as the subcategory. 当我保存临时上下文并与主上下文合并时,以某种方式调用setSubcategory作为子类别传递nil。 This often results in the SpecialItem object being saved with myProperty set to nil. 这通常会导致在myProperty设置为nil的情况下保存SpecialItem对象。 I don't know what is calling setSubcategory. 我不知道调用setSubcategory是什么。 I'm not explicitly calling setSubcategory:nil. 我没有明确地调用setSubcategory:nil。

My question is, what is happening and how can I fix this? 我的问题是,发生了什么以及如何解决这个问题?

This is the managed object implementation: 这是托管对象实现:

@interface SpecialItem : GenericItem
@property (nonatomic, strong) Subcategory *subcategory;
@property (nonatomic, strong) MyProperty *myProperty;
@end

@implementation SpecialItem
@dynamic subcategory;
@dynamic myProperty;

- (void)setSubcategory:(Subcategory *)subcategory
{
   [self willChangeValueForKey:@"subcategory"];
   [self willChangeValueForKey:@"myProperty"];

   [self setPrimitiveValue:subcategory forKey:@"subcategory"];
   [self setPrimitiveValue:subcategory.category.myProperty forKey:@"myProperty"];

   [self didChangeValueForKey:@"myProperty"];
   [self didChangeValueForKey:@"subcategory"];
}
// ...

The managed object contexts are setup like so: 托管对象上下文的设置如下:

self.tempContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
self.tempContext.parentContext = self.dataManager.mainContext;

Eventually I have this: 最终我有这个:

[self saveTempContext];

Here is the saveContext implementation: 这是saveContext实现:

- (void)saveContext
{
   LogAndPrint(@"Before save.");
   [self.tempContext performBlockAndWait:^{
      NSError *error = nil;
      if (![self.tempContext save:&error])
      {
         LogAndPrint(@"Error occurred while saving context: %@", error);
      }
   }];

   LogAndPrint(@"Middle of save.");

   [self.dataManager.mainContext performBlockAndWait:^{
      NSError *error = nil;
      if (![self.dataManager.mainContext save:&error])
      {
         LogAndPrint(@"Error occurred while saving context: %@", error);
      }
   }];

   [self.dataManager synchronize];
   LogAndPrint(@"After save.");
}

Here is the synchronize implementation: 这是同步实现:

- (void)synchronize
{
   LogAndPrint(@"Synchronizing Core Data changes.");
   if (self.persistentContext.hasChanges) {
      [self.persistentContext performBlockAndWait:^{
         NSError *error =  nil;
         if (![self.persistentContext save:&error]) {
            LogAndPrint(@"Error occurred while saving persistent context: %@", error);
         }
      }];
   }
}

I was never able to figure out why this was happening. 我无法弄清楚为什么会这样。 But I did find a solution that works. 但我确实找到了一个有效的解决方案。 I changed the code that was calling setSubcategory to call a new method named [SpecialItem updateSubcategory:subcategory]. 我更改了调用setSubcategory的代码来调用名为[SpecialItem updateSubcategory:subcategory]的新方法。

- (void)updateSubcategory:(Subcategory *)subcategory
{
   self.subcategory = subcategory;
   self.myProperty = subcategory.category.myProperty;
}

This fixed it and the code has been working fine for several months now. 这修复了它,代码已经运行了好几个月了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM