我正在编写一个自定义UI控件,我很好奇关于初始化的标准实践(特别是依赖于控件的委托)。像大多数控件一样,我的控件依赖于委托来提供关于如何呈现自身的重要信息。
当控件从NIB内使用时,initWithCoder:
和awakeFromNib
方法被正确调用,并且通过IBOutlet
很好地设置了委托。awakeFromNib
调用称为setupControl
的辅助方法,该方法与委托交互以设置我的控件。生活的很好!
然而,当我使用initWithFrame:
手动创建控件时,显然awakeFromNib
从未被调用。我很好奇其他开发人员是如何同时支持IB和编程控制创建的。我可以看到一些支持程序化情况的技术:
- 强制开发者调用
initWithFrame:
,然后是setDelegate:
,最后是setupControl
。不是太繁重,但确实暴露了我控制的内部工作(例如。他们必须知道setupControl
) - 修改
initWithFrame:
方法以接受委托。这确实封装了内部工作多一点,然而,我不确定这是一个特别常用的习惯用法(似乎根据委托响应操纵子视图通常被推迟到视图生命周期的稍后,而不是在初始化器中) - 覆盖
setDelegate:
访问器来调用setupControl
方法。我不太喜欢这个,因为它有点副作用编程的味道。
我只是想把它放在那里,看看我忽略了什么技术。想法吗?
谢谢。克雷格
第一:一旦NIB完全加载,-awakeFromNib
将自动发送到控件。这意味着一旦封装在NIB中的整个UI被加载,Cocoa将-awakeFromNib
发送到所有UI组件。它在加载后发送这个的唯一原因是为了避免IBOutlet为nil。通常,如果你以编程方式添加控件,它是在NIB解包和所有UI项加载之后完成的(假设你将IBOutlet连接到你的自定义控件)。因此,在-initWithFrame:
方法的末尾调用-awakeFromNib
没有潜在的问题。
:当以编程方式创建控件时,每个人都期望调用-setDelegate:
。-initWithFrame:
+ -setDelegate:
不是太多,为了得到一个功能控制创建我认为;)