2013-03-05 46 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

相關問題