什么时候 Cocoa 绑定 'set'

When is a Cocoa binding 'set'

我在故事板中设置了一个 NSArrayController,我将模式设置为实体名称,名称为客户端,并绑定了托管对象上下文、选择索引和排序描述符。我的 NSPopupButton 链接到那个数组控制器,当我 运行 时,我在按钮上看到了我期望的所有元素。

现在我在我的代码中做了一个强大的@IBOutlet,我正在尝试访问内容:

let objs = clientArrayController.arrangedObjects as! [Client]
print("I have \(objs.count) clients")

我在 viewDidLoadviewWillAppearviewDidAppear 中尝试了该代码。他们都说0个客户。显然这是不可能的,因为我在 UI 中显示了客户。

我做错了什么?

viewDidLoadviewWillAppearviewDidAppear 可能都被调用 在您的阵列控制器从核心数据存储中收集数据之前 -因此他们(正确地)报告了零计数。要了解数组控制器的 arrangedObjects 数组的任何更改,您可以使用上述方法之一来安装一个监视此对象并报告任何更改的观察器:

// MyPopUpController.swift

var ArrayControllerArrangedObjectsObservationContext = "arrayController.arrangedObjects"


func viewDidLoad() {
    arrayController.addObserver(self, 
        forKeyPath: "arrangedObjects", 
        options: .New | .Old, 
        context: &ArrayControllerArrangedObjectsObservationContext)
}

您有机会响应 observeValueForKeyPath...

中的更改
// MyPopUpController.swift

override func observeValueForKeyPath(keyPath: String, ofObject object: AnyObject, change: [NSObject : AnyObject], context: UnsafeMutablePointer<Void>) {
    switch context {
        case &ArrayControllerArrangedObjectsObservationContext:
            // Check counts here
        default:
            super.observeValueForKeyPath(keyPath, ofObject: object, change: change, context: context)
}

如果您只在启动时需要观察者,在检查计数并完成您需要做的任何事情之后,您应该移除观察者:

// MyPopUpController.swift

arrayController.removeObserver(self, 
    forKeyPath: "arrangedObjects", 
    context: &ArrayControllerArrangedObjectsObservationContext)