如何在Swift 3中将Cocoa绑定到可选类型的属性?

时间:2017-01-17 07:48:57

标签: swift xcode cocoa optional cocoa-bindings

我正在探索将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的标记值

0 个答案:

没有答案