2013-03-05 38 views
1

我在那个地方我正在失去这种头发,所以我想我会接触到那些有Objective-C与线程和核心数据经验的伟大思想。我在从主线程访问的NSPrivateQueue上下文中的线程中插入了托管对象。因此,在高层次上,我使用AFNetworking生成一个线程来发出请求以从服务器检索JSON数据,然后将这些值插入到我的永久存储核心数据中。完成这个之后,我有另一个使用AFNetworking下载一些二进制数据的线程。我已经建立了2个管理上下文此,如下图所示:在上下文之间使用被管理对象的线程

(NSManagedObjectContext *)masterManagedContext { 
if (_masterManagedContext != nil) { 
    return _masterManagedContext; 
} 

NSPersistentStoreCoordinator *coord = [self coordinator]; 
if (coord != nil) { 
    _masterManagedContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType]; 
    _masterManagedContext.stalenessInterval = 0.0; 
    [_masterManagedContext performBlockAndWait:^{ 
     [_masterManagedContext setPersistentStoreCoordinator:coord]; 
    }]; 

} 
return _masterManagedContext; 
} 


// Return the NSManagedObjectContext to be used in the background during sync 
- (NSManagedObjectContext *)backgroundManagedContext { 
if (_backgroundManagedContext != nil) { 
return _backgroundManagedContext; 
} 

NSManagedObjectContext *masterContext = [self masterManagedContext]; 
if (masterContext != nil) { 
    _backgroundManagedContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
    _backgroundManagedContext.stalenessInterval = 0.0; 
    [_backgroundManagedContext performBlockAndWait:^{ 
     [_backgroundManagedContext setParentContext:masterContext]; 
    }]; 
} 

return _backgroundManagedContext; 

}

正如上面我使用的是孩子上下文和父上下文中。当我做我打电话来获取JSON数据我有类似如下:

AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:request success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) { 
     //Initially delete all records in table. This will change 
     [[Singleton sharedInstance]removeEntityObjects:className]; 

      for (int x=0; x < [JSON count]; x++) { 
       NSMutableDictionary *curDict = [JSON objectAtIndex:x]; 
        [[CoreDatam sharedinstance] insertEmployeesWithDictionary:curDict]; 

       }else { 
        /* do nothing */ 
       } 
      } 
     } 

    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error,id JSON) { 

     [delegate performSelector:@selector(didNotCompleteSync:) withObject:className]; 
    }]; 

    [operations addObject:operation]; 
}  

[self.AFClient enqueueBatchOfHTTPRequestOperations:operations progressBlock:^(NSUInteger numberOfCompletedOperations, NSUInteger totalNumberOfOperations) { 
    NSLog(@"Currenlty downloaded table data %d of %d!",numberOfCompletedOperations,totalNumberOfOperations); 

} completionBlock:^(NSArray *operations) { 

    if (_syncInProgress) { 
      [[CoreDatam sharedInstance]updateEmpForId]; 



      [self downloadAllFiles]; 
    } 
}]; 

}`

用于插入功能我有类似如下:

insertEmployeesWithDictionary:curDict { 

[[self backgroundManagedContext]performBlockAndWait:^{ 
Employee *emp = [NSEntityDescription insertNewObjectForEntityForName:@"Employee" 
                inManagedObjectContext:[self backgroundManagedContext]]; 

/* Issues saving null into core data based on type.*/ 
[emp setFirst:[dictCopy objectForKey:@"first"]]; 
[emp setLast:[dictCopy objectForKey:@"last"]]; 


    NSError *error = nil; 
    BOOL saved; 
    saved = [[self backgroundManagedContext] save:&error]; 
    if (!saved) { 
     NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]); 
    } 

    [self saveMasterContext]; 

}]; 

}

问题在于我试图访问上面完成块中的方法中的管理对象:

updateEmpId { 
[self.backgroundManagedContext performBlockAndWait:^{ 
    NSError *error = nil; 
    NSFetchRequest *request = [[NSFetchRequest alloc] initWithEntityName:@"Employee"]; 
    [request setSortDescriptors:[NSArray arrayWithObject: 
           [NSSortDescriptor sortDescriptorWithKey:@"last" ascending:YES]]]; 

    myEmps = [self.backgroundManagedContext executeFetchRequest:request error:nil]; 

for (Employee *moEmp in myEmps) { 
     [[self backgroundManagedContext]refreshObject:moEmp mergeChanges:YES]; 
     moEmp.photo = @'default.pic'; 
} 
       NSError *saveError = nil; 
       if (![self.backgroundManagedContext save:&saveError]) { 
       NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]); 
       } 

      [self saveMasterContext]; 

}

的问题是寻找那些在主线程修改了管理对象的时候,我变得非常不一致的行为。使用父子上下文关系时是否仍然需要传递托管对象ID?如果是这样的话,我怎样才能做到这一点?任何帮助不胜感激。

回答

1

您应该通过NSManagedObjectIDs或在主线程上下文中重新获取,是的。如果您传递对象标识,请在保存新Employee对象后从后台上下文中获取标识,并在父上下文中使用existingObjectWithID:error:以在那里实例化它们。或者只需重新执行masterManagedContext中代码块updateEmpId的获取请求。

+0

所以,即使我在AFNetworking线程和主线程中使用相同的上下文。我仍然需要在两个方法之间传递对象ID。对于上面的例子,你有没有一个如何做到这一点的例子?只是想了解一个想法,因为我不必在不同的线程上使用coredata和管理对象。谢谢。 – doubleace3 2013-03-06 03:58:01

相关问题