将模型数据指针与NSWindow相关联

时间:2020-02-11 22:53:19

标签: objective-c macos cocoa appkit

我有一个MacOS appkit应用程序,其中有很多不同的NSWindows(数百个),它们都是从情节提要中创建的。

许多NSWindows的容器视图具有复杂的嵌入式视图/视图控制器层次结构。

在初始化期间,有必要知道与任何给定NSWindow相关联的模型对象,以便可以正确初始化其子视图和控件。由于任何NSController都可以知道其NSView,并且任何NSView都可以知道其NSWindow,因此将该信息与NSWindow存储在一起将是很好的选择。

最好为NSWindow设置一个“ representedObject”,但与NSViewController不同,它实际上并没有一个。

为每个NSWindow故事板对象创建一个简单的自定义类(从一个小的基类派生)是唯一真正的解决方案,因此视图层次结构下的NSViews和NSViewControllers可以获取我的模型数据(指针)?

澄清:我们数百个情节提要中的NSWindow对象中,很少有自定义类或从NSWindow派生的代码。因此,尽管类别绝对有助于将API添加到类中以访问与NSWindow相关的模型数据,但对于创建属性或实例变量并在所有这些NSWindow故事板上进行初始化都是没有帮助的。 / p>

我最终提出了一种简单却令人讨厌的错误解决方案,没有人可以复制:

我们的应用程序未使用NSDocument,它将提供将NSWindow对象与文档/模型体系结构关联的功能。因此,我们的目标是允许每个NSController和NSView都访问初始化视图的控件所需的适当的单个文档模型对象。

Apple工程专家已警告我,我不能依赖于创建和初始化视图和子视图的顺序。这使得将数据传递到复杂的情节提要板嵌入式子视图中变得棘手且容易出错。

但是-在主线程上使用所有UI的情况下,MacOS上的单个应用程序无法创建,初始化和显示一个情节提要板,而又有另一个情节提要板初始化和显示中断该过程(至少不是我们的用户-调用的应用程序故事板)。因此,简单的解决方案是...

...使临时设置具有所需文档模型指针的应用程序级别的全局变量。那,以及基于堆栈的锁计数,以确保不会违反上述假设。 糟糕的设计有效的解决方案

没有人需要提醒我为什么这不好。但是,如果有更好的解决方案,它可以逃脱我的测试。我发现,即使viewDidLoad和viewWillAppear也无法可靠地指向其NSWindow ...

1 个答案:

答案 0 :(得分:0)

不知道您的应用程序结构;您将需要一种将模型指针分配给每个单独窗口的机制。这将需要添加一些代码 somewhere NSWindow子类似乎确实合适。

在AppKit MVC模式中,模型数据通常位于视图和视图控制器之间。试图将模型与窗口相关联在某种程度上与这种模式作斗争。

话虽这么说; Objective C runtime确实允许您使用类别将自定义属性添加到现有类。这是使用关联引用实现的。相关功能为:

objc_setAssociatedObject
objc_getAssociatedObject
objc_removeAssociatedObjects

article很好地说明了这种方法的优点和缺点。