我在那個地方我正在失去這種頭髮,所以我想我會接觸到那些有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?如果是這樣的話,我怎樣才能做到這一點?任何幫助不勝感激。
所以,即使我在AFNetworking線程和主線程中使用相同的上下文。我仍然需要在兩個方法之間傳遞對象ID。對於上面的例子,你有沒有一個如何做到這一點的例子?只是想了解一個想法,因爲我不必在不同的線程上使用coredata和管理對象。謝謝。 – doubleace3 2013-03-06 03:58:01