0

除非需要,否则我喜欢不公开类变量。在我看到的大多数objective-c代码中,变量被声明为属性,即使它们永远不会被外人使用。

@interface DetailViewController : UIViewController {
    __weak IBOutlet UILabel *name;
}

对比

@interface DetailViewController : UIViewController

@property (weak, nonatomic) UILabel *name;

作为一名软件工程专业的学生,​​在我看来,这严重违反了封装等原则,并可能导致大型项目中出现不必要的耦合。

我确实了解使用属性的 KVC 方面,但不明白为什么要公开显然只打算在类内部使用的变量,例如上面的 UILabel。

有人可以解释为什么这是在 iOS 上使用 Objective-C 时的首选方式吗?

4

3 回答 3

4

属性封装了 iVar 的内存管理(例如分配、保留、复制、强、弱),而直接访问 iVar(实例变量)则没有。这大大减少了内存错误。

非公共属性可以在顶部声明,.m因此没有理由将它们放在标题中:

@interface DetailViewController ()
@property (weak, nonatomic) NSString *name;
@end

属性确实创建了可以访问的 ivars。对于上面的示例,对于显式合成的属性,ivar 将被命名name,而隐式合成的合成属性将具有前导下划线_name

IBOutlets 在标题中声明,即使其他类不需要访问它们,因为它们是必需的,以便 Interface Builder 连接到它们并且 nib 加载系统可以填充出口。IBOutlets 通常是视图,例如您的UILabel.

编辑:

前面关于IBOulets 的段落是 Xcode 3 及更早版本所需的遗留方法。然而,由于 InterfaceBuilder 与 IDE 的其余部分更紧密地集成,较新版本的 Xcode 可以使用在实现文件中定义的出口,就像上面的属性一样。

于 2013-10-18T20:55:14.257 回答
1

你看到的是旧风格。早期的 Objective-C 编译器要求您在接口中声明实例变量。但是,默认情况下它们是@protected,所以不是每个人都可以使用它们。

当前的最佳实践是,您根本不声明实例变量,而是使用属性,除非您需要声明它们(如果您有一个用于只读属性的自定义 getter,或者有一个用于读写属性的自定义 getter 和 setter,则没有实例变量是自动生成的),您在 .m 文件中声明它们,除非有人真的需要访问它们,您在 .m 文件中声明属性和方法,除非有人需要访问它们,并且您根本不声明方法除非需要。

在头文件中将属性声明为只读,并在实现中将其重新声明为读/写也是很常见的。

换句话说,隐藏你可以隐藏的东西。

于 2014-06-06T17:26:08.397 回答
0

第一个示例表明您希望将标签用作 Xib 或 Storyboard 的出口。这个答案揭示了这种情况:https ://stackoverflow.com/a/1236985/171933

但是,一般来说,您不需要将内部实例变量声明为属性。实际上,您可以将它们完全移出标题,方法是将它们放入您的 .m 文件中,如下所示:

@implementation DetailViewController 
{
    NSInteger _someValue;
    UILabel *_someLabel;
}

这样,您实际上只能保留标题中应该对外部可见的内容。这些东西通常要么是属性,要么是普通的旧方法。

于 2013-10-18T20:57:09.293 回答