Core Data 在 fetchObjects 中保留两个对象而不是 27 个

Posted

技术标签:

【中文标题】Core Data 在 fetchObjects 中保留两个对象而不是 27 个【英文标题】:Core Data keeps two objects instead 27 in fetchObjects 【发布时间】:2014-07-07 19:09:56 【问题描述】:

第一步: 从 Json 数据上传(数据总数 = 27 个对象)然后我想将所有这些对象保留在我的核心数据中; 第二步: 一段时间后,我再次检查我的 Json 是否有新对象。比较核心数据对象计数和 Json 对象计数,如果不同,我将把这些对象添加到我的核心数据中。但是我的核心数据在第二步中有错误的对象计数(fetchObjects 中有 2 个对象)。 总之,我想将所有对象从 Json 复制到我的核心数据,并且每十秒钟我检查一次 Json 中的新对象。 这是我的以下代码:

- (NSInteger) isNewData: (NSArray *) fetchedObjects

    ///////////json part
    NSURLRequest* urlRequest =  [NSURLRequest requestWithURL:[NSURL          URLWithString:getMessageURL] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60.0];
    NSData * data = [NSURLConnection sendSynchronousRequest:urlRequest returningResponse:nil error:nil];
    _json = [NSJSONSerialization JSONObjectWithData:data options:kNilOptions error:nil];
    ///////////core data part
    //NSManagedObjectContext *context = [self managedObjectContext];
    /*NSError *error;
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription
                               entityForName:@"Entity" inManagedObjectContext:context];
    [fetchRequest setEntity:entity];
    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];*/
    /////////if part
    NSLog(@"%d",fetchedObjects.count);
    return _json.count - fetchedObjects.count;


- (void) loadDataToCoreDataFromJson: (NSInteger) odds andSecond: (NSManagedObjectContext *) context

    //core data connection
    Entity *newList = [NSEntityDescription
                   insertNewObjectForEntityForName:@"Entity"
                   inManagedObjectContext:context];
    newList = [NSEntityDescription insertNewObjectForEntityForName:@"Entity" inManagedObjectContext:context];
    for (int i = 0; i < odds; i++)//?
    
        //NSManagedObjectContext *context = [self managedObjectContext];

        newList.login = [[_json objectAtIndex:_json.count - odds + i] objectForKey:@"login"];
        newList.message = [[_json objectAtIndex:_json.count - odds + i] objectForKey:@"message"];
        newList.date = [[_json objectAtIndex:_json.count - odds + i] objectForKey:@"date"];
        [context save:nil];
    



- (void) loadDataFromCoreDataToArrays : (NSArray*) fetchedObjects

    _getDate = [[NSMutableArray alloc] init];
    _getMessage = [[NSMutableArray alloc] init];
    _getLogin = [[NSMutableArray alloc] init];
    ///////////core data part connection
    //NSManagedObjectContext *context = [self managedObjectContext];
    for (int i = 0; i < fetchedObjects.count; i++)
    
        Entity * info = [fetchedObjects objectAtIndex:i];
        [_getLogin addObject:info.login];
        [_getMessage addObject:info.message];
        [_getDate addObject:info.date];
    



- (void) chating

    AppDelegate* appDelegate = [UIApplication sharedApplication].delegate;
    NSManagedObjectContext *context = appDelegate.managedObjectContext;
    NSError *error;
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
    NSEntityDescription *entity = [NSEntityDescription
                               entityForName:@"Entity" inManagedObjectContext:context];
    [fetchRequest setEntity:entity];
    NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
    NSInteger odds = [self isNewData: fetchedObjects]; //0 if no data, if > 0 then there are N new data;
    if (odds != 0)
    
        AudioservicesPlaySystemSound(kSystemSoundID_Vibrate);
        [self loadDataToCoreDataFromJson: odds andSecond:context];
        [self loadDataFromCoreDataToArrays: fetchedObjects];
        [self reloadMyTableView];
    


- (void) viewWillAppear:(BOOL)animated

    [super viewWillAppear:animated];
    _buttonSend.enabled = NO;
    [self loadUserDefault];
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
        _connects++;
        NSLog(@"return message");
        dispatch_async(dispatch_get_main_queue(), ^
            [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(chating) userInfo:nil repeats:YES];
            [NSTimer scheduledTimerWithTimeInterval:10 target:self selector:@selector(reloadMyTableView) userInfo:nil repeats:YES];
        );
    );

我认为我在 Core Data 上做错了。感谢大家的帮助。

【问题讨论】:

【参考方案1】:

作为指导:

    不要同步加载,而是选择异步 不要依赖计数,它现在可能有效,但比较唯一标识符是一个更好的长期解决方案 向服务器发送您已有的信息,这样它就不需要再告诉您这些信息(节省带宽,让用户满意) 始终验证结果,然后在适当的情况下检查从提供该结果的 API 返回的 error - 例如在保存上下文或执行提取请求时 不要在没有引用它们的情况下启动计时器 - 您确实需要稍后能够invalidate它们...

此外,当您调用 loadDataFromCoreDataToArrays: 时,您并没有 fetchedObjects 中的所有对象 - 您已将它们添加到上下文中,但您尚未将它们添加到 fetchedObjects 或重新获取。

【讨论】:

如何在 loadDataFromCoreDataToArrays 中从 Core Data 中获取所有对象,以及如何在 fetchObjects 中添加。谢谢你的回答。 不要只检查错误。检查方法的响应。如果该响应指示错误THEN检查错误。 @user3813671 将项目添加到数组中(使其可变),这比运行新的获取请求更有效。

以上是关于Core Data 在 fetchObjects 中保留两个对象而不是 27 个的主要内容,如果未能解决你的问题,请参考以下文章

带有 NSFetchResultController 的 CoreData:使用 fetchObjects 中的属性进行的无效更新

Drupal - 致命错误sessionhandler

Core Data

RESTkit,Core Data:在将对象传输到 Core Data 之前对其进行处理

EF6 System.Data.Entity.Core.EntityKey 在 Entity Framework Core 中的等价物是啥?

RestKit / Core Data:远程删除的实体不会从 Core Data 中删除