面试题答案
一键面试1. 更好地组织协议定义
- 模块化协议:将相关功能的协议放在同一个模块中,比如在一个电商 App 项目中,将商品展示模块涉及的协议,如
ProductDisplayDelegate
相关协议放在ProductModule
内。这样在后期维护和查找时,能快速定位到特定功能相关的协议。 - 命名规范:协议命名遵循清晰且有意义的规则,一般以其所服务的类或功能命名,例如
ViewControllerDelegate
明确表示这是为视图控制器服务的委托协议。 - 分层协议:对于复杂业务,可以分层定义协议。例如在社交 App 开发中,有处理网络请求数据的底层协议,如
NetworkDataFetcherDelegate
,还有处理界面展示逻辑的高层协议,如UserProfileViewDelegate
,通过分层使协议职责更清晰。
2. 优化委托链管理
- 集中管理:可以创建一个专门的
DelegateManager
类来管理委托关系。在一个音乐播放 App 中,不同界面(播放界面、列表界面等)与播放引擎之间的委托关系,通过DelegateManager
来统一维护。这样当需要修改或添加委托时,只需要在这个类中操作,避免在多个地方分散管理导致混乱。 - 使用弱引用集合:在管理委托链时,使用弱引用集合(如
NSHashTable
以弱引用方式存储委托对象)。比如在一个直播 App 中,主播端有多个观众端连接,主播端维护一个弱引用集合存储观众端的委托,当观众端对象销毁时,委托关系自动解除,不会造成内存泄漏。 - 生命周期管理:明确委托关系的生命周期,例如在视图控制器的
viewDidLoad
方法中建立委托关系,在dealloc
方法中移除委托。在一个地图导航 App 中,地图视图控制器在加载时设置与导航逻辑模块的委托关系,在控制器销毁时及时断开,防止野指针问题。
3. 避免循环引用
- 使用弱引用:在委托属性声明时使用
weak
关键字。例如在一个自定义视图CustomView
中,它有一个委托属性delegate
,声明为weak var delegate: CustomViewDelegate?
。这样当视图控制器持有CustomView
,而CustomView
通过委托回调视图控制器时,不会形成循环引用。 - 中间层解耦:引入一个中间层对象来打破循环引用。例如在一个即时通讯 App 中,聊天界面视图控制器
ChatViewController
与聊天消息发送模块MessageSender
可能会形成循环引用,此时可以引入一个ChatCoordinator
中间层对象,ChatViewController
与ChatCoordinator
建立委托关系,ChatCoordinator
再与MessageSender
交互,从而避免了直接的循环引用。