代码之家  ›  专栏  ›  技术社区  ›  Kaelin Colclasure

来自NIB的nsWindowController子类初始化不使用-initwitcoder:?

  •  4
  • Kaelin Colclasure  · 技术社区  · 14 年前

    我已经将nswindowcontroller的自定义子类添加到我的cocoa项目中,并将子类的一个实例添加到应用程序的nib中。我希望在加载NIB时看到对-initWithCoder:方法的重写,但没有。为了进行调试,我添加了一个常规的-init方法,并在它上面设置了一个断点,并且在加载NIB时,我确实击中了断点。

    这实际上可以使一些事情对我来说更简单(例如设置windownibname),但我不明白为什么cocoa会这样做。我读过的所有文档都建议-initwitcoder:是我应该覆盖的地方。为什么这种情况不同?

    3 回复  |  直到 14 年前
        1
  •  4
  •   Brian Webster    14 年前

    我假设要在Interface Builder中实例化窗口控制器,需要拖动 NSObject 实例到NIB文件,然后分配自定义 NSWindowController 子类作为对象的类,对吗?如果是这样,那么我认为这里的关键区别在于,您要处理的是实例化一个通用对象,而不是一个包含在ib调色板中的自定义对象。

    大多数情况下,当您使用ib创建和配置对象时,您在各个检查器中指定的设置将使用 encodeWithCoder: 方法保存NIB文件时。然后在应用程序中加载该NIB文件时,将使用 initWithCoder: 方法。

    但是,在这个通用对象实例的情况下,接口生成器不一定知道任何关于被实例化对象的类的信息。因为您可以指定任何要实例化的类名,如果您指定了一个ib没有通过调色板或框架加载的类,那么它就无法使用 NSCoding . 所以我相信当你实例化一个这样的通用对象时,它会被初始化 init 而不是 编码器: 因为它不是用 编码器: 一开始保存NIB文件时。

    我不知道这是否在任何地方被记录在案,但我想这就是为什么你看到了不同之处。我也不认为它是特定于 NSWindowController窗口控制器 但是,相反,您可以从实例化为泛型的任何对象中看到相同的行为。 NSO对象 在ib中,不考虑特定的类。

        2
  •  0
  •   Kaelin Colclasure    14 年前

    我还是没有正式的答案 为什么 可可就是这样,但在实际应用中似乎很方便。我用下面的-init方法定义了一个nswindowcontroller子类,它的工作方式很迷人。

    - (id)init;
    {
        if ((self = [super initWithWindowNibName:@"MumbleMumbleSheet"]) != nil) {
            …
        }
        return self;
    }
    

    如果调用了-initwithcoder:,我就必须弄清楚如何履行调用super-initwithcoder:方法的隐式义务,并仍然获得用于加载的正确的-windownibname。这样更直接。

    我还是希望能找到一些文件 这一类是不同的,解释了为什么和如何,但在缺乏文献的情况下,有经验证据。

        3
  •  0
  •   No one in particular    14 年前

    编码方法用于已序列化并保存到文件中的类。

    你在这里做的是不同的。您正在将控制器类构建到可执行文件中。这意味着不需要从文件中读取类本身,因为它是正在运行的应用程序二进制文件的一部分。

    当使用这个控制器类时,您需要提供一个init方法,在其中提供NIB文件名。为什么?好吧,您已经将编译类作为exe的一部分,但不知道NIB文件是什么。这就是你提供知识的方式。

    这样想。控制器类是exe的一部分。需要在它和NIB文件之间建立一些链接。一种方法是扫描所有的NIB文件,寻找对这个控制器的引用。那将是低效的。在init和所有引导中提供名称。

    换句话说,你从你的实验中学到了一些重要的教训。干得好,太沉迷了。