我已经将NSManagedObject
子类化添加了一些处理对象关系集排序的属性,然后将这个排序存储在属性中。我使用KVO来确定原始集合的更改时间和nil存储的属性,以便使用更新的集合数据进行排序。
然而,我遇到的问题是这些集合的更改是在后台上下文中执行,然后合并回主上下文,更新NSManagedObject
子类但不触发我和KVO观察者已经设置好了。这反过来意味着我不会存储所有财产。
如何通过合并更新NSManagedObject
子类?
下面是我的子类中的KVO结构:
#pragma mark - Awake
- (void)awakeFromFetch
{
[super awakeFromFetch];
/*-------------------------------*/
[self addObserver:self
forKeyPath:@"comments"
options:NSKeyValueObservingOptionNew
context:NULL];
}
#pragma mark - KVO
- (void) observeValueForKeyPath:(NSString *)keyPath
ofObject:(id)object
change:(NSDictionary *)change
context:(void *)context
{
if ([object isEqual:self])
{
if ([keyPath isEqualToString:@"comments"])
{
_orderedComments = nil;
}
}
}
#pragma mark - OrderedComments
- (NSArray *)orderedComments
{
if (!_orderedComments)
{
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"dateCreated"
ascending:NO];
NSArray *sortDescriptors = @[sortDescriptor];
_orderedComments = [self.comments sortedArrayUsingDescriptors:sortDescriptors];
}
return _orderedComments;
}
其他信息:
我使用父子模式来控制我的NSManagedObjectContexts
所以当我创建主要上下文时:
_managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
并在每个NSOperation
上下文中创建子/背景上下文:
_localManagedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSConfinementConcurrencyType];
[_localManagedObjectContext setParentContext:[CDSServiceManager managedObjectContext]];
[_localManagedObjectContext setUndoManager:nil];
[_localManagedObjectContext setMergePolicy:NSMergeByPropertyObjectTrumpMergePolicy];
(CDSServiceManager
是一个允许访问主上下文的辅助类)
我使用以下内容来控制合并:
- (void) saveLocalContextChangesToMainContextWithSuccess:(void (^)(void))success
failure:(void (^)(NSError *error))failure
{
NSError *localManagedObjectContentSaveError = nil;
if (![self.localManagedObjectContext save:&localManagedObjectContentSaveError])
{
DLog(@"Error to saving local context: %@", [localManagedObjectContentSaveError userInfo]);
if (failure)
{
failure(localManagedObjectContentSaveError);
}
}
else
{
[[CDSServiceManager managedObjectContext] performBlock:^
{
NSError *mergeSaveError = nil;
if (![[CDSServiceManager managedObjectContext] save:&mergeSaveError])
{
DLog(@"Error saving main context: %@", [mergeSaveError userInfo]);
if (failure)
{
failure(mergeSaveError);
}
}
else
{
if (success)
{
success();
}
}
}];
}
}
这是从NSOperation
子类调用的。