我有一种奇怪的行为。
当应用程序首次启动时,我会执行多个GET
请求以下载一些数据。
我使用AFURLConnectionOperation batchOfRequestOperations
下载我的数据:
以下是多个GET
请求的代码:
-(void)refreshData:(NSMutableArray *)mutableOperations
{
NSArray *operations = [AFURLConnectionOperation batchOfRequestOperations:mutableOperations progressBlock:^(NSUInteger numberOfFinishedOperations, NSUInteger totalNumberOfOperations) {
NSLog(@"%lu of %lu complete", numberOfFinishedOperations, totalNumberOfOperations);
} completionBlock:^(NSArray *operations) {
[self.delegate dataRefreshingDone];
}];
[[NSOperationQueue mainQueue] addOperations:operations waitUntilFinished:NO];
}
在mutableOperation中,我有一个下载一些Directors
的操作,当我收到我的导演时,我将它们保存在我的CoreData中:
GET
导演的操作代码:
- (AFHTTPRequestOperation *)getOperationGetDirectors
{
NSURL *URL = [NSURL URLWithString:[NSString stringWithFormat:@"%@/api/diretors", [NSString stringWithUTF8String:kBaseURL]]];
NSURLRequest *request = [NSURLRequest requestWithURL:URL];
AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
operation.responseSerializer = [AFJSONResponseSerializer serializer];
[operation.responseSerializer setAcceptableContentTypes:[operation.responseSerializer.acceptableContentTypes setByAddingObject:@"text/html"]];
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if ([[responseObject objectForKey:@"success"] intValue] == 1) {
// I GET THE MANAGED
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext* context = [appDelegate managedObjectContext];
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Director"
inManagedObjectContext:context]];
NSMutableArray *directorsArray= [responseObject objectForKey:@"data"];
for (NSMutableDictionary *directorReceived in directorsArray) {
// Do lots of things with the context.
Director *director = (Director *)[NSEntityDescription
insertNewObjectForEntityForName:@"Director"
inManagedObjectContext:context];
NSArray *availableKeys = [[director.entity attributesByName] allKeys];
if ([propertyName isEqualToString:@"mostFamousMovie"]) {
// This case is a relationship. A director has a most famous movie.
// So we get the most famous movie thanks to the id of the movie in the JSON
NSDictionary *mostFamousMovieReceived = [mostFamousMovieReceived objectForKey:propertyName];
Movie *movie = (Movie *)[GenericCoreData getEntityById:[mostFamousMovieReceived objectForKey:@"id"] forEntityName:@"Movie"];
if (movie) {
[director setValue:movie forKey:propertyName];
}
}
else if ([availableKeys containsObject:propertyName]) {
[director setValue:[directorReceived objectForKey:propertyName] forKey:propertyName];
}
}
NSError *error;
if ([context save:&error]) {
}
}
}
failure:^(AFHTTPRequestOperation *operation, NSError *error) {
// ERROR HANDLING
}];
return operation;
}
我保存后,然后继续DirectorsViewController
(我取了所有导演,将它们显示在桌面视图上)。它运作得很好。
我的getEntityById
班级GenericCoreData
+ (NSManagedObject *)getEntityById:(id)entityId forEntityName:(NSString *)entityName
{
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext* context = [appDelegate managedObjectContext];
NSFetchRequest * fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:entityName
inManagedObjectContext:context]];
NSError *error = nil;
[fetchRequest setIncludesPropertyValues:YES];
[fetchRequest setPredicate:[NSPredicate predicateWithFormat:@"id == %@", entityId]];
NSArray *fetchResult = [context executeFetchRequest:fetchRequest error:&error];
NSManagedObject *managedObjectFound = nil;
if (fetchResult && [fetchResult count] == 1) {
managedObjectFound = [fetchResult objectAtIndex:0];
}
return managedObjectFound;
}
这是我如何获取我的导演:
AppDelegate *appDelegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
NSManagedObjectContext* context = [appDelegate managedObjectContext];
NSFetchRequest *request = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Director"
inManagedObjectContext:context];
[request setEntity:entity];
NSError *error = nil;
NSLog(@"FETCH Director IN DIRECTOR VIEW CONTROLLER = %@", [context executeFetchRequest:request error:&error]);
NSMutableArray *mutableFetchResults = [[context executeFetchRequest:request error:&error] mutableCopy];
if (error) {
// Handle the error.
}
// We set the array of directors array for the tableView
[self setDirectorsArray:mutableFetchResults];
之后...如果我重新编译,或者我只是通过模拟器杀死应用。如果我回到我的应用程序。我的抓取请求返回空数组,或只有一个导演的数组。这是不可能的,因为我节省了更多的导演,并且在第一次启动应用程序时fetch工作得非常好。
经过一些研究......我想知道是否与ManagedObjectContext
存在冲突......事实是它是在successBlock
的操作中执行的......或者可能是我的实体的关系存在问题......
答案 0 :(得分:0)
我检查了我的桌子,我不得不编辑我的关系。他们是双向的。我只需要删除其他表中的关系,并保持关系只在所有者表上(基本上没有反转)......当然,在某些情况下,你需要保持你的反向关系。这取决于你是否需要它。
总而言之,如果您再次遇到此类错误,请查看您的关系。