繁体   English   中英

源文件中的Objective-C成员变量vs属性

[英]Objective-C member variable vs property in source file

我了解Object-C中成员变量和属性之间的区别,但是有一件事让我感到困惑。 请参阅以下代码。

测试

@interface test : NSObject

@end 

测试

@interface test()
{
  NSString *memberStr;
}
@property (nonatomic, strong) NSString *properyStr;
@end

如图所示,memberStr和propertyStr无法从外部看到。 我想知道它们之间有什么区别。 因为当我想使用局部变量时,我不怎么选择解决方案。 谢谢!

properyStr将自动生成getter和setter。

您可以如下定义propertyStr自定义设置器。 当您使用self.propertyStr ,它将为您创建一个默认对象。 对于初始化诸如NSMutableArrayNSMutableDictionary等对象将很有用。

- (NSString *)properyStr
{
     if(_propertyStr == nil)
     {
          _propertyStr = @"";
     }
     return _propertyStr;
}

memberStr将没有这些选项。

我了解Object-C中成员变量和属性之间的区别

我不确定你会这么做。

成员变量是仅在实例方法范围内可见的变量。

属性是可以设置或获取的类的某些属性。 编译器将编写适当的getters和(可选)setters,并将自行组织存储,除非您覆盖其中任何内容。

成员变量和属性都可以在@implementation@interface

成员变量永远不能被不相关的类直接访问,无论它在何处声明。 如果在@interface则可以由子类访问它。

始终可以读取属性,也可以选择由任何其他类编写属性,而不管其在何处声明。 外部类可以使用键值编码机制,即使@property不可见。

因此,您可能会问的问题:

问)为什么要将成员变量放入@interface

答:不太可能。 它将其暴露给子类,但通常这样做是设计缺陷。 但是,在过去,由于旧的Objective-C运行时的工作原理,必须将所有成员变量放入@interface 因此,较旧的代码和惯用的程序员有时仍会遵循这种模式。

问)为什么我要声明仅对@implementation可见的属性?

答:不太可能。 但是,在过去,这是创建在@interface中不可见的成员变量的唯一方法,因此人们在短时间内处理大多数成员变量的方法也是如此。 同样,您可以声明一些内容,比如说retain ,然后使用getter / setter并假设正在进行正确的内存管理,因此在引入ARC之前,它就充当了某种语法糖。 与前面的答案一样,因此有些人仍然通过习惯来这样做,而有些代码由于年纪较大而仍然这样做。 这不是您如今经常要做的事情。

编辑:更好的摘要:属性调整您的类接口 成员变量调整其实现 在面向对象的编程中,您应该将这两件事视为完全不相交的

一个面向对象编程的主要目的之一是有一堆离散的演员是说:“我可以做X”与它们究竟是如何做到这一点是别人的事。

一个属性说明一个类可以做什么。 成员变量的好处在于类如何实现。

从语义上讲,它们是完全独立的问题。

memberStr的第一个是实例变量或ivar。

如果您为此拥有一个属性设置,则不再需要memberStr

@interface test()
@property (nonatomic, strong) NSString *properyStr;
@end

这样做的原因是,将与setter和getter方法一起为您自动创建ivar。

与接口文件(.h)相比,在实现文件(.m)界面中声明属性的唯一区别是,该属性仅对此类是私有的。 拥有此功能有很多优点,例如,您可能不想让类外的任何人知道它,但是您希望该属性仍在该类的范围内。 它们以这种方式使用的一件事是,当您拥有一个声明为public的只读属性,但仍希望该setter属于此类的范围时。 所以你可能会有类似

。H

@interface MyObject : NSObject

// Other classes can see this property as it is public however they can only see
// it's getter and not the setter
@property (nonatomic, readonly) NSString *firstName;

@end

.m

@interface MyObject()

// But we still want to use the setter for this class only.
@property (nonatomic, strong) NSString *firstName;

@end

否则, 除了私有的只有类; 在实现文件(.m)中具有该属性与在接口文件(.h)中具有该属性完全相同,它们将起作用并执行相同的操作。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM