【问题标题】:I can fetch my entities that I save only on the first launch. If I relaunch the app, I can't fetch my entities我可以获取仅在第一次启动时保存的实体。如果我重新启动应用程序,我将无法获取我的实体
【发布时间】:2014-08-08 16:07:00
【问题描述】:

我有一个奇怪的行为。 首次启动应用程序时,我执行多个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(我获取我所有的导演以将它们显示在 tableView 上)。效果很好。

我的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的操作中执行的...或者可能有问题我的实体的关系...

【问题讨论】:

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


    【解决方案1】:

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

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-09
      • 2019-01-29
      • 2012-05-01
      • 2014-10-22
      • 1970-01-01
      • 2013-08-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多