与 AppDelegate 跨场景通信 (Cocoa, swift)
Communicating with AppDelegate across scenes (Cocoa, swift)
在 Xcode 6(也是 7)中,我正在寻找如何获取 managedObjectContext 并在不同场景的 ViewController 中使用它。
- 我开始了一个新的Cocoa项目,点击了'Use CoreData'
- 在 CoreData 中添加了一个实体,为其生成了一个 managedObject
- 添加了数组控制器,并将其绑定到实体
- 我想将数组控制器绑定到 managedObjectContext,但是我还想将 tableView(在我的视图控制器中)绑定到数组控制器。它们在不同的场景中,这似乎意味着不同的命名空间。
我尝试过的事情:
在 ViewController:
中设置一个实例变量
var managedObjectContext: NSManagedObjectContext!
在viewDidAppear()
中我添加了:
if let app = NSApplication.sharedApplication().delegate! as? AppDelegate {
if let context = app.managedObjectContext{
managedObjectContext = context
} else {
print("There was no context available, didn't work")
}
}
然后我将 table 的列绑定到实体的属性。并且 cocoa 绑定自动完成,这意味着至少可以正确识别上下文。
然而,当我 运行 它时,它静静地失败了:'Cannot perform operation without a managed object context'。调试时上下文被设置为一个真实的对象,但我不知道它是否真的被初始化了。我查看了文档和 cocoa 绑定故障排除,但这似乎是核心数据问题。
(我看过这里:Getting managedObjectContext from AppDelegate 但我无法覆盖 swift 中的正常初始化)
我给你举了一个例子。我有一个 Entity
,名为 Person
,具有 2 个属性,name
和 age
。这是我的 ViewController
:
import Cocoa
class ViewController: NSViewController {
// ManagedObjectContext from AppDelegate
lazy var moc: NSManagedObjectContext = {
let appDel = NSApplication.sharedApplication().delegate as! AppDelegate
return appDel.managedObjectContext
}()
override func viewDidLoad() {
super.viewDidLoad()
// Populate some sample data
let firstPerson = NSEntityDescription.insertNewObjectForEntityForName("Person", inManagedObjectContext: moc) as! Person
firstPerson.name = "Jesse Pinkman"
firstPerson.age = 25
}
}
在 IB 中,我有一个 table 视图和一个阵列控制器。将阵列控制器的实体设置为 Person
:
并将数组控制器的托管对象上下文绑定到 viewcontroller 的托管对象上下文,在我的示例中 self.moc
:
然后将您的 table 视图的列绑定到您的阵列控制器。
对于它的价值,您可以绑定到 IB 中的 Application
,模型密钥路径为 self.delegate.managedObjectContext
。这是又快又脏的方法。
有些人认为这很糟糕,主要是因为他们认为应用委托一开始就不应该拥有 MOC。我认为拥有核心数据堆栈的应用程序委托很好。
但我要警告它不是面向未来的。如果您想为 VC 创建一个子 MOC,并通过跳过保存轻松 "undo" 该场景中的所有本地更改,您最终会创建和维护VC.
上的 moc 属性
在 Xcode 6(也是 7)中,我正在寻找如何获取 managedObjectContext 并在不同场景的 ViewController 中使用它。
- 我开始了一个新的Cocoa项目,点击了'Use CoreData'
- 在 CoreData 中添加了一个实体,为其生成了一个 managedObject
- 添加了数组控制器,并将其绑定到实体
- 我想将数组控制器绑定到 managedObjectContext,但是我还想将 tableView(在我的视图控制器中)绑定到数组控制器。它们在不同的场景中,这似乎意味着不同的命名空间。
我尝试过的事情: 在 ViewController:
中设置一个实例变量var managedObjectContext: NSManagedObjectContext!
在viewDidAppear()
中我添加了:
if let app = NSApplication.sharedApplication().delegate! as? AppDelegate {
if let context = app.managedObjectContext{
managedObjectContext = context
} else {
print("There was no context available, didn't work")
}
}
然后我将 table 的列绑定到实体的属性。并且 cocoa 绑定自动完成,这意味着至少可以正确识别上下文。
然而,当我 运行 它时,它静静地失败了:'Cannot perform operation without a managed object context'。调试时上下文被设置为一个真实的对象,但我不知道它是否真的被初始化了。我查看了文档和 cocoa 绑定故障排除,但这似乎是核心数据问题。
(我看过这里:Getting managedObjectContext from AppDelegate 但我无法覆盖 swift 中的正常初始化)
我给你举了一个例子。我有一个 Entity
,名为 Person
,具有 2 个属性,name
和 age
。这是我的 ViewController
:
import Cocoa
class ViewController: NSViewController {
// ManagedObjectContext from AppDelegate
lazy var moc: NSManagedObjectContext = {
let appDel = NSApplication.sharedApplication().delegate as! AppDelegate
return appDel.managedObjectContext
}()
override func viewDidLoad() {
super.viewDidLoad()
// Populate some sample data
let firstPerson = NSEntityDescription.insertNewObjectForEntityForName("Person", inManagedObjectContext: moc) as! Person
firstPerson.name = "Jesse Pinkman"
firstPerson.age = 25
}
}
在 IB 中,我有一个 table 视图和一个阵列控制器。将阵列控制器的实体设置为 Person
:
并将数组控制器的托管对象上下文绑定到 viewcontroller 的托管对象上下文,在我的示例中 self.moc
:
然后将您的 table 视图的列绑定到您的阵列控制器。
对于它的价值,您可以绑定到 IB 中的 Application
,模型密钥路径为 self.delegate.managedObjectContext
。这是又快又脏的方法。
有些人认为这很糟糕,主要是因为他们认为应用委托一开始就不应该拥有 MOC。我认为拥有核心数据堆栈的应用程序委托很好。
但我要警告它不是面向未来的。如果您想为 VC 创建一个子 MOC,并通过跳过保存轻松 "undo" 该场景中的所有本地更改,您最终会创建和维护VC.
上的 moc 属性