在 Interface Builder 中设置委托与使用 setDelegate: 有啥区别?

Posted

技术标签:

【中文标题】在 Interface Builder 中设置委托与使用 setDelegate: 有啥区别?【英文标题】:What is the difference between setting the delegate in Interface Builder vs using setDelegate:?在 Interface Builder 中设置委托与使用 setDelegate: 有什么区别? 【发布时间】:2010-01-29 23:12:47 【问题描述】:

我正在尝试使用 Interface Builder 为滚动视图设置委托。

如果我有这样的代码:

MyScrollViewDelegate * delegate = [[MyScrollViewDelegate alloc] init];
[scrollView setDelegate:delegate];

在 viewDidLoad 中,一切正常。

如果我打开 Interface Builder,添加一个 NSObject 并将类设置为 MyScrollViewDelegate,然后将 scrollView 的委托链接到我的 MyScrollViewDelegate 实例并检查 viewDidLoad 中的 [scrollView 委托],它看起来像 MyScrollViewDelegate 的一个实例,我可以交互有了它,设置属性等,看起来不错。

但是,当我在滚动视图中滚动时,我得到一个 NSInvalidArgumentException:

 *** -[NSCFArray scrollViewDidScroll:]: unrecognized selector sent to instance 0x3d319a0
 *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[NSCFArray scrollViewDidScroll:]: unrecognized selector sent to instance 0x3d319a0'

所以,问题:

    在 Interface Builder 中设置委托与使用 setDelegate: 有什么区别? 为什么控制台中是“[NSCFArray scrollViewDidScroll:]”,而不是[MyScrollViewDelegate scrollViewDidScroll:]? 我做错了什么?

【问题讨论】:

【参考方案1】:

setDelegate: 本身没有区别。

但是,您遇到了内存管理问题。问题是对象不保留它们的委托(以避免引用循环)。您的委托正在被释放,并且内存被重新用于数组。这就是为什么您会看到一条用于您的委托的消息被分派到一个数组的原因。

由于 Interface Builder 内存管理的怪异,您看到了差异。 “***对象”,即出现在 IB 文档窗口顶层的文件所有者和主菜单旁边的那些对象,对它们有一个不平衡的保留。这让你的代理人在 IB 案例中保持活力。

解决方案是让某些东西(可能是您的应用程序委托)保留滚动视图委托。

见Memory Management of Nib Objects。

【讨论】:

干杯,我为代表添加了一个 IBOutlet。

以上是关于在 Interface Builder 中设置委托与使用 setDelegate: 有啥区别?的主要内容,如果未能解决你的问题,请参考以下文章

在 Interface Builder (XCode 4) 中设置 UIButton 拉伸背景图像

如何在 XCode 5 Interface Builder 中设置accessibilityLabel 或accessibilityIdentifier?

自定义字体仅在 Interface Builder 中设置时可用

如何使用主 iPhone 视图之外的 UI 元素在 Interface Builder 中设置 UIScrollView?

在 Interface Builder 中设置为 UIButton 的 Attributed Title 属性在应用程序中被忽略

Interface Builder 中的自定义字体