Macos 以编程方式和从NIB初始化自定义控件

Macos 以编程方式和从NIB初始化自定义控件,macos,cocoa,nsview,awakefromnib,Macos,Cocoa,Nsview,Awakefromnib,我正在编写一个自定义UI控件,对初始化的标准实践很好奇(特别是依赖于控件的委托)。与大多数控件一样,我的控件依赖委托提供有关如何渲染自身的重要信息 从NIB中使用控件时,将正确调用initWithCoder:和awakeFromNib方法,并通过IBOutlet很好地设置委托awakeFromNib调用名为setupControl的辅助方法,该方法与代理交互以设置我的控件。生活是美好的 但是,当我使用initWithFrame:手动创建控件时,显然从未调用awakeFromNib。我很好奇其他开

我正在编写一个自定义UI控件,对初始化的标准实践很好奇(特别是依赖于控件的委托)。与大多数控件一样,我的控件依赖委托提供有关如何渲染自身的重要信息

从NIB中使用控件时,将正确调用
initWithCoder:
awakeFromNib
方法,并通过
IBOutlet
很好地设置委托
awakeFromNib
调用名为
setupControl
的辅助方法,该方法与代理交互以设置我的控件。生活是美好的

但是,当我使用
initWithFrame:
手动创建控件时,显然从未调用
awakeFromNib
。我很好奇其他开发人员如何处理支持IB和编程控件创建的问题。我可以看到支持编程案例的两种技术:

  • 强制开发人员调用
    initWithFrame:
    ,后跟
    setDelegate:
    ,后跟
    setupControl
    。不太繁重,但确实暴露了我的控件的内部工作(即,他们必须了解
    setupControl
  • 修改
    initWithFrame:
    方法以获取委托。这确实封装了更多的内部工作,但是,我不确定这是否是一个特别常用的习惯用法(而且似乎基于委托响应操纵子视图通常会推迟到视图生命周期的晚一点,而不是在初始化器中)
  • 重写
    setDelegate:
    accessor以调用
    setupControl
    方法。我不太喜欢这个,因为它带有编程的副作用
我只是想把它扔出去看看我忽略了什么技术。想法

谢谢。 克雷格首先:
-awakeFromNib
在NIB完全加载后自动发送到控件。这意味着一旦加载了封装在NIB中的整个UI,就可以将
-awakeFromNib
发送到所有UI组件。它在加载后发送此消息的唯一原因是为了避免无IBOutlet。 通常情况下,如果以编程方式添加控件,则在NIB解包和加载所有UI项后(假设将IBOutlet连接到自定义控件)完成。因此,在
-initWithFrame:
方法末尾调用
-awakeFromNib
没有潜在问题

以及:
当以编程方式创建控件时,每个人都希望调用
-setDelegate:
<代码>-initWithFrame:+
-setDelegate:
对于创建一个函数控件来说并不重要;)

但是,当您说从
initWithFrame:
调用
awakeFromNib
没有问题时,在编程世界中,不会通过
IBOutlet
设置委托。它将在代码中手动设置-这是可以的,但它将在调用
initWithFrame:
后发生,这意味着
initWithFrame:
无法可靠地调用
awakeFromNib
,因为它依赖于正在设置的委托。这就是我正在努力解决的鸡/蛋难题。据我所知,您的控件在初始化和设置阶段依赖于它的委托吗?委托是可选的,初始化任何内容都不需要委托。这里有一个设计问题。