我在构建我的代码时遇到了问题。 我有view
,创建并取决于model
类。模型类负责所有计算和逻辑。这意味着它有很多事情要计算,并从Core数据中获取对象。在不同线程中获取和使用NSManagedObject
关于enter link description here,即在一个线程中获得的每个NSManagedObject,需要在相同的线程中使用。
我的问题是,创建对象需要在不同的线程中获取,因为它需要一些时间来建立模型,但在此之后,我需要从View的主线程中获取对象和属性(例如cellForIndex ...)
我知道,我不是唯一一个拥有这种设计的人。别人如何解决这个问题?
编辑:
要使用代码混凝土这一点。
让我们说我们有UIView
对象MyUIView
和模型对象Model
MyUIView
@interface MyUIView()
@property(nonatomic) Model * model;
@end
@implementation MyUIView
- (void) createModel
{
// privateManagerContext is context manager created with
// NSPrivateQueueConcurrencyType, connected to persistent store
// and sync with "main thread" manager context with
// NSManagedObjectContextDidSaveNotification and NSManagedObjectContextDidSaveNotification
[self.model createWithManagadContext:privateManagerContext];
}
// ASSUME THAT THIS CODE IS CALLED AFTER
- (void) getNumberOfSomeProperties
{
int number = [self.model getNumberOfProperties];
}
- (void) getProperties
{
NSArray *array = [self.model properties]
}
// OR WE HAVE TO TRIGGERED SOME LONG CALCULATION
- (void) triggerLongCalculation
{
[self.model longCalculation];
}
- (void) afterNotifyModelIsCompletedCalculating
{
[self doSomeWork];
[self getProperties];
....
}
@end
型号
@interface Model()
@property(nonatomic) NSArray * cashedProperties;
@end
@implementation MyUIView
- (void) createWithManagadContext:(NSManagedObjectContext *) privateManagerContext
{
dispatch_async(self.model_queue, ^(void){
// Here we fetch objects and do some calculations
[self populateModel];
/// Model is complete
[Notifications notifyModelIsCompletedCreating:self];
});
}
- (void) longCalculation
{
dispatch_async(self.model_queue, ^(void){
// NO CORE DATA FETCH INVOLVED
[Notifications notifyModelIsCompletedCalculating:self];
});
}
- (int) getNumberOfProperties
{
return self.cashedProperties.count;
}
- (NSArray) properties
{
NSMutableArray * a = [[NSMutableArray alloc]init];
for (Property * p in self.cashedProperties) {
[a addObject:p.name];
}
return a;
}
@end
所以在这个假设的类中,你将如何处理所有的NSManagedObject和NSManagedObjectContext?
编辑2:
我使用,我创建的appdelegate两个托管对象上下文,一个私人,一个主要的模式,并在它们之间建立同步。
- (NSManagedObjectContext *)managedObjectContext
{
if (__managedObjectContext != nil) {
return __managedObjectContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
__managedObjectContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
[__managedObjectContext setPersistentStoreCoordinator:coordinator];
}
return __managedObjectContext;
}
- (NSManagedObjectContext *) privateQueueContext
{
if (_privateQueueContext != nil) {
return _privateQueueContext;
}
NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
if (coordinator != nil) {
_privateQueueContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[_privateQueueContext setPersistentStoreCoordinator:coordinator];
}
return _privateQueueContext;
}
- (id)init
{
self = [super init];
if (self) {
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contextDidSavePrivateQueueContext:)
name:NSManagedObjectContextDidSaveNotification
object:[self privateQueueContext]];
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(contextDidSaveMainQueueContext:)
name:NSManagedObjectContextDidSaveNotification
object:[self managedObjectContext]];
}
return self;
}
#pragma mark - Notifications
- (void)contextDidSavePrivateQueueContext:(NSNotification *)notification
{
@synchronized(self) {
[self.managedObjectContext performBlock:^{
NSArray* objects = [notification.userInfo valueForKey:NSUpdatedObjectsKey];
for (NSManagedObject* obj in objects) {
NSManagedObject* mainThreadObject = [self.managedObjectContext objectWithID:obj.objectID];
[mainThreadObject willAccessValueForKey:nil];
}
[self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];
}];
}
}
- (void)contextDidSaveMainQueueContext:(NSNotification *)notification
{
@synchronized(self) {
[self.privateQueueContext performBlock:^{
NSArray* objects = [notification.userInfo valueForKey:NSUpdatedObjectsKey];
for (NSManagedObject* obj in objects) {
NSManagedObject* mainThreadObject = [self.privateQueueContext objectWithID:obj.objectID];
[mainThreadObject willAccessValueForKey:nil];
}
[self.privateQueueContext mergeChangesFromContextDidSaveNotification:notification];
}];
}
}
您可以在主线程中加载对象,也可以在计算完成后创建该对象的非受管版本并将其传递给主线程。 – Avi