上下文的正常初始化是这样的:
lazy var context : NSManagedObjectContext = {
let context = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
context.persistentStoreCoordinator = self.coordinator
return context
}()
但为什么我可以用这种方式初始化上下文:
var managedObjectContext : NSManagedObjectContext?
lazy var note: Note? = {
if let context = self.managedObjectContext {
return NSEntityDescription.insertNewObjectForEntityForName("Note", inManagedObjectContext: context) as? Note
}
return .None
}()
如果我没有设置persistentStoreCoordinator,那么上下文将以哪种方式存储实体。顺便说一下,这不是在demo中创建的第一个上下文,它只是一个名为Node的manageredobject的上下文
在线等待..........
整个代码是:
import UIKit
import CoreData
class CreateNoteViewController : UIViewController, UITextFieldDelegate, UITextViewDelegate {
var managedObjectContext : NSManagedObjectContext?
lazy var note: Note? = {
if let context = self.managedObjectContext {
return NSEntityDescription.insertNewObjectForEntityForName("Note", inManagedObjectContext: context) as? Note
}
return .None
}()
@IBOutlet var titleField : UITextField!
@IBOutlet var bodyField : UITextView!
@IBOutlet var attachPhotoButton : UIButton!
@IBOutlet var attachedPhoto : UIImageView!
override func viewDidAppear(animated: Bool) {
super.viewDidAppear(animated)
if let image = note?.image {
attachedPhoto.image = image
view.endEditing(true)
} else {
titleField.becomeFirstResponder()
}
}
@IBAction func saveNote() {
note?.title = titleField.text
note?.body = bodyField.text
if let managedObjectContext = managedObjectContext {
do {
try managedObjectContext.save()
}
catch let error as NSError {
print("Error saving \(error)", terminator: "")
}
}
performSegueWithIdentifier("unwindToNotesList", sender: self)
}
func textFieldShouldReturn(textField: UITextField) -> Bool {
saveNote()
textField.resignFirstResponder()
return false
}
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject!) {
if segue.identifier == "AttachPhoto" {
if let nextViewController = segue.destinationViewController as? AttachPhotoViewController {
nextViewController.note = note
}
}
}
}
viewcontroller的功能是从本地闹钟中选择一张照片,并保存标题,节点用于保存所有信息,所以作者确实使用了默认上下文(即使我不知道为什么他不使用默认上下文),他初始化一个新的上下文来保存节点,甚至没有设置任何东西,它的惊人,甚至是他没有设置的文件路径的路径, 我将告诉你默认的堆栈:
import Foundation
import CoreData
class CoreDataStack: CustomStringConvertible {
var modelName : String
var storeName : String
var options : [String : AnyObject]?
init(modelName:String, storeName:String, options: [String : AnyObject]? = nil) {
self.modelName = modelName
self.storeName = storeName
self.options = options
}
var description : String {
return "context: \(context)\n" +
"modelName: \(modelName)" +
"storeURL: \(storeURL)\n"
}
var modelURL : NSURL {
return NSBundle.mainBundle().URLForResource(self.modelName, withExtension: "momd")!
}
var storeURL : NSURL {
var storePaths = NSSearchPathForDirectoriesInDomains(.ApplicationSupportDirectory, .UserDomainMask, true) as [String]
let storePath = String(storePaths[0]) as NSString
let fileManager = NSFileManager.defaultManager()
do {
try fileManager.createDirectoryAtPath(storePath as String, withIntermediateDirectories: true, attributes: nil)
} catch let error as NSError {
print("Error creating storePath \(storePath): \(error)")
}
let sqliteFilePath = storePath.stringByAppendingPathComponent(storeName + ".sqlite")
return NSURL(fileURLWithPath: sqliteFilePath)
}
lazy var model : NSManagedObjectModel = NSManagedObjectModel(contentsOfURL: self.modelURL)!
var store : NSPersistentStore?
lazy var coordinator : NSPersistentStoreCoordinator = {
let coordinator = NSPersistentStoreCoordinator(managedObjectModel: self.model)
do {
self.store = try coordinator.addPersistentStoreWithType(
NSSQLiteStoreType,
configuration: nil,
URL: self.storeURL,
options: self.options)
} catch var error as NSError {
print("Store Error: \(error)")
self.store = nil
} catch {
fatalError()
}
return coordinator
}()
lazy var context : NSManagedObjectContext = {
let context = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
context.persistentStoreCoordinator = self.coordinator
return context
}()
}
答案 0 :(得分:0)
您的第一个代码段创建了一个托管对象上下文:
lazy var context : NSManagedObjectContext = {
let context = NSManagedObjectContext(concurrencyType: .MainQueueConcurrencyType)
context.persistentStoreCoordinator = self.coordinator
return context
}()
您的第二个代码段无法创建托管对象上下文:
var managedObjectContext : NSManagedObjectContext?
lazy var note: Note? = {
if let context = self.managedObjectContext {
return NSEntityDescription.insertNewObjectForEntityForName("Note", inManagedObjectContext: context) as? Note
}
return .None
}()
第二个片段使用Swift可选展开来检查self.managedObjectContext
是否为零。如果它不是,则将其分配给局部变量context
。您不必在此处设置持久性存储协调器,因为您没有创建托管对象上下文。此代码假定self.managedObjectContext
已在其他位置创建(可能在第一个代码段中)。
如果没有持久性存储协调器,托管对象上下文就没有多大用处,您无法对其进行任何有用的操作。您尤其无法使用它保存数据。但由于您的第二个代码段并未创建托管对象上下文,因此这并不重要。
答案 1 :(得分:0)
协调器不是init方法的参数有很多可能的原因。
由于上下文可以与商店协调器或父上下文一起使用,因此在每种情况下还包括并发类型param的init方法将很麻烦,并使子类化更加棘手。因此,他们选择了一次设置一次属性,即,如果再次设置它们,则会出现不一致情况,即“上下文已具有协调器;无法替换。”。
允许在准备使用上下文之前创建上下文,这为应用程序的初始化例程提供了更大的灵活性。首先,在创建堆栈的各个部分,模型,协调器,上下文等方面提供了灵活性。其次,可以先将上下文传递给视图控制器,然后再将存储加载并在上下文上设置协调器。并且viewController可以侦听NSPersistentStoreCoordinatorStoresDidChangeNotification
,然后检查上下文是否现在具有有效的协调器,然后执行其视图更新。