Core Data浅谈系列之八 : 关于并发

本文介绍了如何在CoreData中使用多线程处理数据,包括创建临时上下文、监听保存通知及合并更改等技巧,避免UI阻塞并提高程序效率。
有时候,我们需要有个worker thread来做一些密集型或者长耗时的任务,以避免阻塞住UI,给用户不好的体验。比如从网络上获取一批数据,然后解析它们,并将其输出到存储文件中。这时候,由于数据层发生了变动,我们希望通知到主线程更新UI —— 这就涉及到Core Data的多线程特性。

比如我们一直以来使用的Demo中,添加球员信息的AddPlayerViewController和显示球员列表的PlayerListViewController在进行CURD操作时都是在主ViewController的context中完成的,这通过维持一个属性cdViewController指向主ViewController来实现: 
[cpp]  view plain copy
  1. #pragma mark -   
  2. #pragma mark - UITableView Delegate  
  3.   
  4. - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath  
  5. {  
  6.     [tableView deselectRowAtIndexPath:indexPath animated:YES];  
  7.   
  8.     Team *teamObject = [self.teamArray objectAtIndex:indexPath.row];  
  9.     PlayerListViewController *playerListVC = [[[PlayerListViewController alloc] init] autorelease];  
  10.     playerListVC.team = teamObject;  
  11.     playerListVC.cdViewController = self;  
  12.     [self.navigationController pushViewController:playerListVC animated:YES];  
  13. }  
以及:
[cpp]  view plain copy
  1. #pragma mark -   
  2. #pragma mark - Player CURD  
  3.   
  4. - (void)addPlayer:(id)sender  
  5. {  
  6.     AddPlayerViewController *addPlayerVC = [[[AddPlayerViewController alloc] init] autorelease];  
  7.     addPlayerVC.cdViewController = self.cdViewController;  
  8.     addPlayerVC.team = self.team;  
  9.     [self presentModalViewController:addPlayerVC animated:YES];  
  10. }  
对于比较小的Demo,这么写代码是可以接受的,虽然也会觉得传递得有点长。
当程序的代码规模比较大,或者说处理的数据比较多时,我们可以通过引入并发特性来做一点优化。

通过创建临时的context来添加球员信息: 
[cpp]  view plain copy
  1. - (IBAction)addBtnDidClick:(id)sender  
  2. {  
  3.     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{  
  4.         NSManagedObjectContext *tmpContext = [[NSManagedObjectContext alloc] init];  
  5.         [tmpContext setPersistentStoreCoordinator:sharedPersistentStoreCoordinator];  
  6.   
  7.         // We don't check the user input.  
  8.         Player *playerObject = [NSEntityDescription insertNewObjectForEntityForName:@"Player" inManagedObjectContext:tmpContext];  
  9.         playerObject.name = self.nameTextField.text;  
  10.         playerObject.age = [NSNumber numberWithInteger:[self.ageTextField.text integerValue]];  
  11.         playerObject.team = self.team;  
  12.   
  13.         NSError *error = NULL;  
  14.         if (tmpContext && [tmpContext hasChanges] && ![tmpContext save:&error]) {  
  15.             NSLog(@"Error %@, %@", error, [error localizedDescription]);  
  16.             abort();  
  17.         }  
  18.   
  19.         dispatch_async(dispatch_get_main_queue(), ^{  
  20.             [self dismissModalViewControllerAnimated:YES];  
  21.         });  
  22.     });  
  23. }  
为了响应其它线程的变化, 参考此文档,我们可以先监听消息,然后合并发生了的变化:
[cpp]  view plain copy
  1. [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(mocDidSaveNotification:) name:NSManagedObjectContextDidSaveNotification object:nil];  
  2.   
  3.   
  4. - (void)mocDidSaveNotification:(NSNotification *)notification  
  5. {  
  6.     NSManagedObjectContext *savedContext = [notification object];  
  7.   
  8.     if (savedContext == self.managedObjectContext) {  
  9.         return ;  
  10.     }  
  11.   
  12.     if (savedContext.persistentStoreCoordinator != self.persistentStoreCoordinator) {  
  13.         return ;  
  14.     }  
  15.   
  16.     dispatch_async(dispatch_get_main_queue(), ^{  
  17.         NSLog(@"Merge changes from other context.\n");  
  18.         [self.managedObjectContext mergeChangesFromContextDidSaveNotification:notification];  
  19.     });  
  20. }  
这么做了之后,我们尝试添加一名球员,会得到如下错误信息:
[plain]  view plain copy
  1. 2013-01-21 09:56:08.300 cdNBA[573:617] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: 'Illegal attempt to establish a relationship 'team' between objects in different contexts  
这是由于我们把主线程context中的team对象传递到临时创建的context中进行操作了。在Core Data的多线程环境中,我们只能传递objectID或者重新fetch:
[cpp]  view plain copy
  1. addPlayerVC.teamID = [self.team objectID];  
  2.   
  3. // ...  
  4.   
  5. playerObject.team = (Team *)[tmpContext objectWithID:self.teamID];  
这样可以执行过去,控制台输出:
[plain]  view plain copy
  1. 2013-01-21 10:11:12.834 cdNBA[687:1b03] void _WebThreadLockFromAnyThread(bool), 0x83a91c0: Obtaining the web lock from a thread other than the main thread or the web thread. UIKit should not be called from a secondary thread.  
  2. 2013-01-21 10:11:12.932 cdNBA[687:c07] Merge changes from other context.  
第二行日志说明合并变化了,不过第一行告诉我们在非主线程里面访问了一些UI方面的东西。这是由于上面在global_queue里面访问了UITextField,把访问UI的代码提到外面即可。

BTW,在iOS 5以后,苹果提供了更为便捷有效的parent-child context机制,可以参见 这里
内容概要:本文围绕列车-轨道-桥梁交互仿真研究,基于Matlab平台构建数值模型,系统分析列车运行过程中轨道与桥梁结构间的动态相互作用机制。研究涵盖多体动力学建模、耦合系统运动方程求解、边界条件设定及仿真结果可视化等关键环节,重点揭示高速行车条件下基础设施的振动传递规律与力学响应特征。该仿真方法可有效评估结构安全性、舒适性指标及疲劳寿命,为轨道交通工程的设计优化与运维管理提供理论支撑和技术路径。文中配套提供了完整的Matlab代码实现方案及操作说明,便于用户复现、验证和拓展相关研究。; 适合人群:具备Matlab编程基础和结构动力学、车辆动力学等相关专业知识的研究生、科研人员及从事铁路工程、桥梁工程与交通系统安全评估的工程技术人才,尤其适合开展轨道交通耦合振动课题的研究者。; 使用场景及目标:①用于高校与科研机构进行列车-轨道-桥梁耦合系统动力学特性的教学演示与科学研究;②支撑高速铁路桥梁的设计优化、运营安全性评估与减振降噪方案验证;③为复杂交通基础设施的多物理场耦合仿真提供建模思路与代码参考。; 阅读建议:建议读者结合所提供的Matlab代码逐模块深入研读,重点关注系统建模假设、质量-刚度-阻尼矩阵构建方法及数值积分算法的实现细节,同时可通过调整参数进行敏感性分析,进一步掌握仿真模型的适用范围与优化方向。
内容概要:本文系统研究了非线性薛定谔方程的物理信息神经网络(PINN)求解方法,提出一种将物理规律嵌入深度学习模型的科学计算新范式。通过构建全连接神经网络架构,将非线性薛定谔方程及其初始/边界条件作为损失函数的核心组成部分,实现了在无须大量标注数据的前提下对复值偏微分方程的高精度数值求解。该方法充分利用自动微分技术精确计算方程残差,有效融合了数据驱动与模型驱动的优势,在光学孤子传播、量子系统演化等典型场景中展现出优异的逼近能力与泛化性能。文中配套提供了完整的Python实现代码,涵盖网络搭建、损失定义、训练优化与结果可视化全流程。; 适合人群:具备Python编程能力与深度学习基础知识,熟悉偏微分方程理论及科学计算的理工科研究生、科研人员,以及从事光学、量子物理、流体力学等领域建模与仿真的工程技术人员。; 使用场景及目标:① 掌握PINN方法的基本原理与实现技巧;② 学习如何将复杂物理方程转化为可训练的神经网络损失项;③ 应用于非线性光学、玻色-爱因斯坦凝聚、水波动力学等问题的仿真与预测;④ 为相关科研课题提供可复现的算法原型与代码参考。; 阅读建议:建议读者结合所提供的Python代码进行动手实践,重点理解神经网络对微分算子的近似机制、损失函数的多任务加权策略以及训练过程中的超参数调优方法,进而可迁移至其他非线性偏微分方程的求解任务,拓展其在交叉学科中的应用边界。
源码下载地址: https://pan.quark.cn/s/a4b39357ea24 微软推出的【AZ-900微软认证】是一项针对初学者的基础级云服务资格认证,其目的在于帮助学习者掌握云概念、微软Azure服务的运作机制以及云解决方案的核心知识。获得这一认证后,考生将能够清晰地理解云计算领域的基础术语、服务模式(包括IaaS、PaaS、SaaS等)以及这些服务在Azure平台上的实际应用方式。 在【必过考题】部分,我们可以观察到两个重点议题,它们分别聚焦于PaaS(平台即服务)的概念阐释和云成本的计算方式。 在第一个议题中,考生被要求辨别关于PaaS的正确性描述。PaaS平台提供了一个开发环境,但并不允许用户直接访问操作系统(Box 1: No)。比如,Azure Web Apps服务可以用来部署web应用,但用户无法直接管理虚拟机或IIS系统。另一方面,PaaS确实具备自动扩展的功能(Box 2: Yes),这表示可以根据实际需求自动增加负载均衡的虚拟机以支持web应用的运行。PaaS框架还为开发人员提供了构建和调整云端应用的工具,预置的应用组件能够有效缩短新应用的编程周期(Box 3: Yes)。 第二个议题同样关注云计算理念的理解,尤其强调IT支出从资本性支出(CapEx)向运营性支出(OpEx)的转型思想。传统的IT投资通常被视为CapEx,而云计算的按需付费机制使企业能够将这部分开支转化为OpEx,从而在财务规划上获得更大的自由度。 在为AZ-900考试做准备时,考生需要特别关注以下几个核心知识点: 1. **云服务模式**:深入理解IaaS(基础设施即服务)、PaaS和SaaS(软件即服务)之间的差异及其各自的应用情境。 2. **Azure服务*...
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值