我可以获取我在第一次启动时保存的实体。如果我重新启动应用程序,我无法获取我的实体

时间:2014-08-08 16:07:01

标签: objective-c core-data afnetworking objective-c-blocks nsmanagedobject

我有一种奇怪的行为。 当应用程序首次启动时,我会执行多个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的操作中执行的......或者可能是我的实体的关系存在问题......

1 个答案:

答案 0 :(得分:0)

我检查了我的桌子,我不得不编辑我的关系。他们是双向的。我只需要删除其他表中的关系,并保持关系只在所有者表上(基本上没有反转)......当然,在某些情况下,你需要保持你的反向关系。这取决于你是否需要它。

总而言之,如果您再次遇到此类错误,请查看您的关系。