标签:
2:了解工程代码
默认情况下,在应用的AppDelegate.swift文件中,将为我们提供一些与Core Data相关的代码。在文件的顶部我们将看到导入了Core Data 框架。那是因为在创建工程的时候,选中Use Core Data,xcode将在AppDelegate.Swift自动为我们生成相关Core Data stack 代码.
import UIKit
import CoreData
在AppDelegate类中还包含了四个懒加载的存储属性:
applicationDocumentsDirectory 类型为NSURL
managedObjectModel类型为 NSManagedObjectModel
managedObjectContext类型为 NSManagedObjectContext
persistentStoreCoordinator类型为 NSPersistentStoreCoordinator
下面一起了解一下各个属性:
applicationDocumentsDirectory属性
以如下简单的代码方式创建文件存储目录,NSFileManager用于获取文件的目录。 lazy var applicationDocumentsDirectory: NSURL = { // The directory the application uses to store the Core Data store file. This code uses a directory named "hua.Core_Data_Stack" in the application's documents Application Support directory. let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask) return urls[urls.count-1] }()
managedObjectContext:我们经常使用它与Core Data进行交互。managedObjectContext的初始化操作在闭包中进行。
在闭包中,我们首先引用持久化存储协调者,然后在初始化managedObjectContext的时候配置.MainQueueConcurrencyType为参数,我们将在后续的文章中了解更多有关于并发类型。使用.MainQueueConcurrencyType表示managedObjectContext默认在主线程列队中进行工作。
在我们返回managedObjectContext对象之前,我们需要设置persistentStoreCoordinator属性,没有persistentStoreCoordinator对象,managedObjectContext将毫无用处。
lazy var managedObjectContext: NSManagedObjectContext = { // Returns the managed object context for the application (which is already bound to the persistent store coordinator for the application.) This property is optional since there are legitimate error conditions that could cause the creation of the context to fail. let coordinator = self.persistentStoreCoordinator var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType) managedObjectContext.persistentStoreCoordinator = coordinator return managedObjectContext }()
persistentStoreCoordinator
正如我们前面所看到的,在配置managedObjectContext的时候有访问persistentStoreCoordinator属性,下面我们看一下实现,代码看起来有点多,但是不要担心,我们一点一点分析。
lazy var persistentStoreCoordinator: NSPersistentStoreCoordinator = { // The persistent store coordinator for the application. This implementation creates and returns a coordinator, having added the store for the application to it. This property is optional since there are legitimate error conditions that could cause the creation of the store to fail. // Create the coordinator and store let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel) let url = self.applicationDocumentsDirectory.URLByAppendingPathComponent("SingleViewCoreData.sqlite") var failureReason = "There was an error creating or loading the application's saved data." do { try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL: url, options: nil) } catch { // Report any error we got. var dict = [String: AnyObject]() dict[NSLocalizedDescriptionKey] = "Failed to initialize the application's saved data" dict[NSLocalizedFailureReasonErrorKey] = failureReason dict[NSUnderlyingErrorKey] = error as NSError let wrappedError = NSError(domain: "YOUR_ERROR_DOMAIN", code: 9999, userInfo: dict) // Replace this with code to handle the error appropriately. // abort() causes the application to generate a crash log and terminate. You should not use this function in a shipping application, although it may be useful during development. NSLog("Unresolved error \(wrappedError), \(wrappedError.userInfo)") abort() } return coordinator }()
在闭包中,首先我们初始化NSPersistentStoreCoordinator类的实例,传入管理对象模型(managedObjectModel)作为参数,后面我们将学习managedObjectModel属性。正如我们所看到的,创建NSPersistentStoreCoordinator对象是非常容易的,但是NSPersistentStoreCoordinator并没有使用任何的持久化管理,所以在闭包中,我们将加载持久化存储(persistent store)并添加到persistentStoreCoordinator。
同时我们也指定了具体的存储路径,使用applicationDocumentsDirectory属性。
最后使用NSPersistentStoreCoordinator类的实例方法,addPersistentStoreWithType(_:configuration:URL:options:)进行添加持久化存储,该方法接收4个参数,第一个类型存储类型,我们指定了存储类型为NSSQLiteStoreType,第二个参数用于配置persistent store,传入nil,将使用默认配置。第三个参数是数据存储的位置,即我们事先创建的url路径。第四个参数是一个字典,用于对persistent store进行配置,暂时传入nil。
因为addPersistentStoreWithType是可出错的,所以我们使用do-catch进行捕获异常,如果没有错误将添加persistent store到persistentStoreCoordinator上。如果添加persistent store错误,那么意味着persistent store有问题,我们需要采取相应的步骤解决,在catch闭包中我们打印了错误的原因并且调用了abort方法。注意:我们不能够在生产环境调用该方法,它会让应用奔溃。
补充一点:
Core Data提供了4种NSPersistentStore方式:3个原子性的一个非原子性的:在我们进行任何的读数据或者写数据操作之前需要对原子性持久化存储进行完全的反序列化并加载到内存。相反,非原子性存储能够加载自己的块到存储,如果需要。
简单的预览一下Core Data内嵌的持久化存储类型:
1:NSQLiteStoreType是由SQLite database支持。这是Core Data唯一种非原子的存储类型,有着轻量和高效的存储使用,在大多数iOS工程中,这是最好的选择,Xcode中的Core Data 模板,默认就是使用NSQLiteStoreType类型进行存储。
2:NSXMLStoreType支持xml文件,是所有类型中最可读性最好的,这种存储类型为原子存储,所以它需要大量的存储使用,NSXMLStoreType类型只适用于OS X。
3:NSBinaryStoreType支持二进制数据文件存储,跟NSXMLStoreType一样,也是原子性存储方式。所以在我们做任何操作之前,整个的二进制文件必须已经加载到内容。在真实的APP中,很少使用该类型进行存储。
4:NSInMemoryStoreType是一种内存持久化存储类型。在某种程度上,这种存储类型并不是真正的持久化。当APP终止或者在iPhone中退出,那么存储在内存中的数据将消失,所以基本上适用于进行单元测试和一些类型的缓存。
managedObjectModel
闭包中的实现非常简单,应用模型的存储位置是modelURL,并且使用modelURL初始化NSManagedObjectModel类,因为初始化返回额可选值,所以在返回之前我们要进行解包。
lazy var managedObjectModel: NSManagedObjectModel = { // The managed object model for the application. This property is not optional. It is a fatal error for the application not to be able to find and load its model. let modelURL = NSBundle.mainBundle().URLForResource("Core_Data_Stack", withExtension: "momd")! return NSManagedObjectModel(contentsOfURL: modelURL)! }()
在工程导航的左边,我们可以看到Core_Data_Stack.xcdatamodeld文件,该应用数据模型会被编译为.momd文件,该.momd文件管理对象模型。如下图:
工程中很有可能会有一些数据模型文件,NSManagedObjectModel类能够合并多个数据模型(data model)到一个,这是Core Data一个强大和高级的特性。 Core Data framework也支持数据模型版本控制和版本迁移,这能够确保存储在持久化存储中的数据不会被损坏。数据模型文件为空意味着数据模型中并没有包含实体。
最后我们通过一张图来理解Core Data stack中的各个部分:
1:正如上图所示,NSPersistentStoreCoordinator是Core Data的大脑,它能够有一个或者多个persistent stores并且确保数据的保存,加载和缓存等操作。
2:NSPersistentStoreCoordinator通过NSManagedObjectModel知道数据模型。管理对象模型将通过一个或者多个.momd文件创建应用的数据模型
3:应用将通过一个或者多个NSManagedObjectContext类获取对象图形,一个管理对象上下文将通过持久化存储协调器(persistent store coordinator)知道数据模型,管理对象上下文并不知道或者保持引用管理对象模型(managed object model),事实上并不需要这样的引用。当有必要的时候,managed object context 将要求persistent coordinator保存数据。Core Data是模型层的技术。Core Data帮助你构建代表程序状态的模型层。Core Data也是一种持久化技术,它可以将模型的状态持久化到磁盘。但它更重要的特点是:Core Data不只是一个加载和保存数据的框架,它也能处理内存中的数据。
CoreData学习:Core Data Stack(Swift)
标签:
原文地址:http://blog.csdn.net/longshihua/article/details/51462971