我正在探索将Swift用于Mac Cocoa应用程序 - 使用Xcode 8.2.1,似乎我遇到了关于Cocoa绑定的障碍。
在这个基于Core Data文档的玩具项目中,我在StoryBoard中添加了NSArrayController
。我需要将它绑定到NSManagedObjectContext
,以便我的用户界面自己工作。我按照技术Q& A QA1871(https://developer.apple.com/library/content/qa/qa1871/_index.html)中概述的解决方案。
所以我想在我的ViewController类中添加ManagedObjectContext类型的属性。
我自然地宣称它是可选的:
var moc: ManagedObjectContext?
但是当我在InterfaceBuilder的绑定检查器中输入属性名称时,它会抱怨:有一个红色感叹号,将鼠标悬停在它上面会弹出以下错误信息:
“The Managed Object Context binding expects to be bound to an object of type NSObject, but moc is of type ManagedObjectContext?”
它也在运行时失败。
将类型更改为ManagedObjectContext!
无济于事:IB以完全相同的方式抱怨。
将类型更改为非可选ManagedObjectContext
会使IB错误无效,但现在我的ViewController类不再编译了。我得到的错误是:
class ViewController has no initialiser
我完全理解这个错误信息。我可以添加一个初始化器。但是我收到了这条新的错误消息:
property ‘self.moc’ not initialised at super.init call.
我也明白这一点,但我该怎么办?在初始化时,managedObjectContext
尚未知晓。在Objective-C中,我将它设置为nil,我不能这样做,因为该属性不再是可选项。
我真的需要分配一个虚拟的Sentinel ManagedObjectContext,只是为了让编译器满意吗?
这将是丑陋的,远比我们在Objective-C中使用的零值差。在这种情况下,斯威夫特不会比Obj-C更安全,但安全性更低。
我发现这个想法令人厌恶。或者我错过了什么?
或者Swift与Apple推荐的Cocoa绑定模式根本不兼容?那也很可惜。
请注意,等效的Objective-C实现工作得很好。在Objective-C中,属性声明为:
@property (nonatomic, strong) NSManagedObjectContext * _Nullable moc;
编辑:包含两个玩具示例项目的zip存档,一个在Objective-C中,另一个在Swift 3中,可以从http://dl.free.fr/pWkoKQLOc下载
编辑:这是我设置viewController的托管对象上下文的地方:
class Document: NSPersistentDocument {
override func makeWindowControllers() {
let myMoc = self.managedObjectContext
// Returns the Storyboard that contains your Document window.
let storyboard = NSStoryboard(name: "Main", bundle: nil)
let windowController = storyboard.instantiateController(withIdentifier: "Document Window Controller") as! NSWindowController
let myViewController = windowController.contentViewController as! CarViewController
myViewController.moc = myMoc
self.addWindowController(windowController)
}
}
myViewController
由storyboard创建,我只能在初始化后设置moc
。这反过来要求属性是可选的或,以具有虚拟实际值,以用作替换nil
的标记值