美文网首页
创建自己的 Core Data Stack

创建自己的 Core Data Stack

作者: 扬仔360 | 来源:发表于2015-11-26 16:08 被阅读352次

    2017年05月16日17:21:37 更新:

    给一段项目中最新的实现,有时间好好修正下:

    
    protocol UsesCoreDataObjects: class {
        var managedObjectContext: NSManagedObjectContext? { get set }
    }
    
    class CoreDataStack {
        private let modelName: String
        init(modelName: String) {
            self.modelName = modelName
        }
        
        lazy var managedContext: NSManagedObjectContext = self.storeContainer.viewContext
        var savingContext: NSManagedObjectContext {
            return storeContainer.newBackgroundContext()
        }
        
        private lazy var storeContainer: NSPersistentContainer = {
            let container = NSPersistentContainer(name: self.modelName)
            //persistentStoreDescriptions 不写的话是系统自己做,可以自己制定路径
            container.loadPersistentStores { (storeDescription, error) in
                if let error = error as NSError? {
                    print("Unresolved error \(error), \(error.userInfo)")
                }
            }
            return container
        }()
        
        func saveContext () {
            guard managedContext.hasChanges else { return }
            do {
                try managedContext.save()
            } catch let error as NSError {
                    print("Unresolved error \(error), \(error.userInfo)")
            }
        }
    }
    
    

    分割线以上是 2017年05月16日17:21:23 添加的,下面是旧的内容


    简单的 Core Data Stack 就是把使用到的四个常见基本的类封装起来:NSManagedObjectModelNSPersistentStoreNSPersistentStoreCoordinatorNSManagedObjectContext

    创建:CoreDataStack.swift

    第一部分创建 Model 的名字和 Document 的路径URL:
    创建新的 .swift 文件

    import CoreData
    class CoreDataStack {
    
      let modelName = "BALABALA"
    
      //Document's URL
      private lazy var applciationDocumentDirectory: NSURL = {
        let urls = NSFileManager.defaultManager().URLsForDirectory(.DocumentDirectory, inDomains: .UserDomainMask)
        return urls[urls.count-1]
      }()
    }
    

    第二步给类添加懒加载的三个属性 NSManagedObjectContextNSPersistentStoreCoordinatorNSManagedObjectModel

     //NSManagedObjectContext
     //Note: ConcurrencyType 的具体参数会在后面补充添加,暂时先使用 .MainQueueConcurrencyType
     //创建出来Context是完全没有意义的,直到设置了Context的PersistentStoreCoordinator
     lazy var context: NSManagedObjectContext = {
       var managedObjectContext = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
       managedObjectContext.persistentStoreCoordinator = self.psc
       return managedObjectContext
     }()
     
     //NSPersistentStoreCoordinator
     //对StoreCoordinator做懒加载,StoreCoordinator是介与PersistentStore(s)和ObejctModel之间的,所以至少需要一个PersistentStore。
     private lazy var psc: NSPersistentStoreCoordinator = {
       //coordinator init,传入Model,Model指所有的Entity和所有的relationship
       let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.managedObjectModel)
    //    PersisitentStore 的物理存储路径
       let url = self.applciationDocumentDirectory.URLByAppendingPathComponent(self.modelName)
       do{
    //      一些Option配置:
         let options = [NSMigratePersistentStoresAutomaticallyOption : true]
    //addPersistentStoreWithType 选择一个SQLite的type,使用SQLite作为存储模式。
         try coordinator.addPersistentStoreWithType(NSSQLiteStoreType, configuration: nil, URL:url, options: options)
       } catch {
         print("Error adding persistnet store.")
       }
       return coordinator
     }()
     
     //NSManagedObjectModel
     //这里包含着MainBundle里面的momb文件里面的 `.xcdatamodeld` 文件,就是Xcode图形化设计Entity和Relationship的那个文件,使用它来创建ManagedObjectModel
     private lazy var managedObjectModel: NSManagedObjectModel = {
       let modelURL = NSBundle.mainBundle().URLForResource(self.modelName, withExtension: "momd")!
       return NSManagedObjectModel(contentsOfURL: modelURL)!
     }()
    

    添加的每 Property 都对应着 Core Data 的重要组件,使用Lazy Loading,每个组件都依赖其他的组件。

    这些 Property 中只有NSManagedObjectContext是 Public 的 Property,其余的都是 private 修饰。private 修饰的组件外界不需要获取的。

    另外,NSPersistentStoreCoordinator可以通过 NSManagedObjectContext的 Public property 获取。

    而所有的NSManagedObjectModelNSPersistentStore都可以通过NSPersistentStoreCoordinator的Public property 来获取。

    StoreCoordinator做懒加载,它是介与PersistentStore(s)ObejctModel之间的,所以至少需要一个PersistentStore

    最后添加一个方法:

    //保存的方法
    func saveContent () {
      if context.hasChanges {
        do {
          try context.save()
        } catch let error as NSError {
          print("Error: \(error.localizedDescription)")
          abort()
        }
      }
    }
    

    AppDelegate中添加LazyLoading的iVar:

    lazy var coreDataStack = CoreDataStack()
    

    didFinishLaunchingWIthOption的方法中可以给rootViewController中的Context赋值了:

    let navigationController = window!.rootViewController as! UINavigationController
    let viewController = navigationController.topViewController as! ViewController
    viewController.managedContext = coreDataStack.context
    

    接下来在合适的时机调用SaveContent方法,这里就是在applicationDidEnterBackgroundapplicationWillTerminate代理方法中调用:

    coreDataStack.saveContent()
    

    到这里,一个CoreData的栈类就创建完成了,并且已经实现了在应用退出的时候对 Context 进行 saveContent 的操作

    相关文章

      网友评论

          本文标题:创建自己的 Core Data Stack

          本文链接:https://www.haomeiwen.com/subject/mirdhttx.html