Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/objective-c/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios 属性vs实例变量,糟糕的类封装?_Ios_Objective C - Fatal编程技术网

Ios 属性vs实例变量,糟糕的类封装?

Ios 属性vs实例变量,糟糕的类封装?,ios,objective-c,Ios,Objective C,我喜欢不公开类变量,除非需要。在我看到的大多数objective-c代码中,变量被声明为属性,即使外部人员永远不会使用它们 @interface DetailViewController : UIViewController { __weak IBOutlet UILabel *name; } vs 作为一名软件工程专业的学生,我认为这是对封装等原则的严重违反,可能会在大型项目中导致不必要的耦合 我确实理解使用属性的KVC方面,但不理解为什么要公开只在类内部使用的变量,比如上面的UIL

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

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

作为一名软件工程专业的学生,我认为这是对封装等原则的严重违反,可能会在大型项目中导致不必要的耦合

我确实理解使用属性的KVC方面,但不理解为什么要公开只在类内部使用的变量,比如上面的UILabel


有人能解释为什么在iOS上使用Objective-C时,这是首选方法吗?

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

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

@interface DetailViewController ()
@property (weak, nonatomic) NSString *name;
@end
属性确实创建可以访问的IVAR。对于上面的示例,对于显式合成属性,ivar将被命名为
name
,而隐式合成属性将有一个前导下划线
\u name

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

编辑:
上一段关于IBOulet的内容是Xcode 3和更早版本所需的遗留方法。但是,由于InterfaceBuilder与IDE的其余部分的集成更加紧密,新版本的Xcode可以使用在实现文件中定义的插座,就像上面的属性一样。

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

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

@interface DetailViewController ()
@property (weak, nonatomic) NSString *name;
@end
属性确实创建可以访问的IVAR。对于上面的示例,对于显式合成属性,ivar将被命名为
name
,而隐式合成属性将有一个前导下划线
\u name

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

编辑:
上一段关于IBOulet的内容是Xcode 3和更早版本所需的遗留方法。但是,由于InterfaceBuilder与IDE其余部分的集成更加紧密,新版本的Xcode可以使用实现文件中定义的插座,就像上面的属性一样。

第一个示例表明,您希望将标签用作Xib或故事板的插座。这一回答为该案例提供了一些线索:

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

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

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

第一个示例表明,您希望使用标签作为Xib或故事板的出口。这一回答为该案例提供了一些线索:

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

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

这样,您实际上只能在标题中保留外部可见的内容。这些东西通常是属性或简单的旧方法。

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

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

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


换句话说,隐藏你能隐藏的东西

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

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

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