12

抱歉,如果我对这个太挑剔了,但我现在正在学习 iOS 编程,而且我似乎有些人这样声明IBOutlet

IBOutlet 附加到属性

#import <UIKit/UIKit.h>
#import "CustomCell.h"

@interface CustomTableViewController : UITableViewController {
  CustomCell *customCell;
}
@property (nonatomic, retain) IBOutlet CustomCell *customCell;
@end

还有一些这样的声明:

IBOutlet 附加到接口内的声明

#import <UIKit/UIKit.h>
#import "CustomCell.h"

@interface CustomTableViewController : UITableViewController {
  IBOutlet CustomCell *customCell;
}
@property (nonatomic, retain) CustomCell *customCell;
@end

哪一种是正确的声明方式?它们之间有什么区别吗?如果有人知道解释为什么他们把它放在不同的地方,那就太棒了。

非常感谢 :)

4

3 回答 3

12

这两个仍然是“在界面内”,所以你的标题有点混乱,但我明白你在问什么。

在许多情况下,任何一种方法的结果都是相同的,但它们是不同的。一个 IBOutlet 属性将调用该属性的 setter 方法,如果设置该属性应该有一些副作用,那么您就有机会覆盖该 setter。

我更喜欢在属性上使用 outlet,因为我认为它使从 nib 加载的对象的内存管理更加清晰。看看nib 对象的内存管理,我想你会明白我的意思。

nib 文件中的对象创建时保留计数为 1,然后自动释放。在重建对象层次结构时,UIKit 使用 setValue:forKey: 重新建立对象之间的连接,它使用可用的 setter 方法,如果没有可用的 setter 方法,则默认保留对象。这意味着(假设您遵循“出口”中显示的模式)您拥有出口的任何对象仍然有效。但是,如果有任何顶级对象未存储在 outlet 中,则必须保留 loadNibNamed:owner:options: 方法返回的数组或数组中的对象,以防止这些对象过早释放。

IBOutlet ivars 将调用这些 ivars 的 setter(如果它们存在),如果没有找到 setter,则直接保留从 nib 加载的对象。

将属性宣传为 IBOutlet 至少清楚地表明该属性的设置器将始终被使用并遵循为该属性设置的任何内存管理规则。

最后,我认为 IBOutlets 是类的公共接口的一部分,因此最好公开方法(通过属性)以便急切地使用它们而不是使用 -setValue:forKey: 来操作应该是实现细节的支持 ivars .

于 2011-01-08T18:15:28.363 回答
1

这两种风格可以互换,生成的代码或从 nib 加载对象的方式没有区别。真的。

但是,两种样式都有一条多余的线。只需省略 ivar 声明即可。只是线

@property (nonatomic, retain) IBOutlet CustomCell *customCell;

在现代运行时就足够了。

如果您有一个复杂的项目,我建议将所有出口从公共界面移出到单独的头文件中。大多数插座都是私有接口,将它们放在标题中的唯一原因是 Interface Builder 可以找到它们。

于 2011-01-08T20:00:40.757 回答
0

您可以两种方式声明,实际上没有区别。

但是,事情是这样的:

如果你需要你的类有一些具有特殊行为的 ivar 或者它必须从外部访问等,并且它必须是一个属性,那么我会说你有 2 个选项可供选择(附加到属性和内部类接口)。

如果这不是您的情况,请不要创建属性,这不是必需的,只需在您的类接口中进行即可。

希望能帮助到你 ;)

于 2011-01-08T17:55:29.113 回答