首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 移动开发 > 移动开发 >

Core Data多线程环境下pendingChange引发的排序不对有关问题

2013-10-01 
Core Data多线程环境下pendingChange引发的排序不对问题这是一个起初看起来很神奇的问题,大意如下:有一个T

Core Data多线程环境下pendingChange引发的排序不对问题

这是一个起初看起来很神奇的问题,大意如下:

有一个Table,展示多个消息会话,这些消息会话按最新消息时间排序;某种情况下,新收到一条消息,时间展示为最新,但这条消息没有排在最上方。

因为界面上展示的时间是最新的,所以刚开始遇到这个问题的第一反应是看看数据库里面的时间戳是不是正确的,查看后确认时间是最新的没错。

一时陷入了僵局,因为问题很难重现。

所以梳理了下逻辑:

    收到新消息,在后台进行处理,执行save动作;Core Data保存后发出消息通知变更,主线程使用NSFetchedResultsController和UITableView绑定,收到消息后刷新界面;UI界面根据dataSource进行展现,而dataSource根据latestTime进行排序;

因为无法重现,所以先加上了日志输出信息,观察出了发生该现象的时候,主线程都收到两次刷新通知,正常情况下没有。

主线程为什么会发生两次刷新通知呢?

主线程内存上发生了变动;其它线程对持久化层做了写动作,通知到主线程。

所以我就在想主线程在内存上发生了什么变动,找了很久但是没找到什么东西。后来同事一语道破天机,打印出changeValues:

- (void)changeSortKeyInOtherContext:(NSManagedObjectID *)objectId{    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{        NSManagedObjectContext *tmpContext = [[NSManagedObjectContext alloc] init];                NSPersistentStoreCoordinator *sharedPersistentStoreCoordinator = self.cdViewController.persistentStoreCoordinator;        [tmpContext setPersistentStoreCoordinator:sharedPersistentStoreCoordinator];                Player *playerObject = (Player *)[tmpContext objectWithID:objectId];                int age = arc4random() % 100;        playerObject.age = @(age);                int salary = arc4random() % 10000000;        playerObject.salary = @(salary);                NSError *error = NULL;        if (tmpContext && [tmpContext hasChanges] && ![tmpContext save:&error]) {            NSLog(@"Error %@, %@", error, [error localizedDescription]);            abort();        }                [tmpContext release], tmpContext = nil;    });}

这样就可以模拟出问题场景,进而得到验证。

—— Jason Lee @ Hangzhou


热点排行