我理解Object-C中成员变量和属性之间的区别,但有一件事让我感到困惑。请参阅以下代码。
test.h
@interface test : NSObject
@end
test.m
@interface test()
{
NSString *memberStr;
}
@property (nonatomic, strong) NSString *properyStr;
@end
如图所示,从外面看不到memberStr和propertyStr。我想知道它们之间有什么区别。因为当我想使用局部变量时,我不知道如何选择解决方案。 谢谢!
答案 0 :(得分:1)
properyStr
将自动生成getter和setter。
您可以为propertyStr
定义自定义设置器,如下所示。当您使用self.propertyStr
时,它将为您创建一个默认对象。这对于初始化NSMutableArray
,NSMutableDictionary
等对象非常有用。
- (NSString *)properyStr
{
if(_propertyStr == nil)
{
_propertyStr = @"";
}
return _propertyStr;
}
memberStr
将不会有这些选项。
答案 1 :(得分:1)
我理解了Object-C
中成员变量和属性之间的区别
我不确定你这么做。
成员变量是仅在实例方法范围内可见的变量。
属性是可以设置或获取的类的某个属性。编译器将编写适当的getter和(可选)setter,并为自己组织存储,除非你覆盖任何这些东西。
成员变量和属性都可以在@implementation
或@interface
中声明。
不相关的类永远不能直接访问成员变量,无论它在何处被声明。如果它在@interface
中,则子类可以访问它。
无论声明的位置如何,都可以随时读取属性,也可以选择由任何其他类写入。外部类可以使用键值编码机制,即使@property
对它们不可见。
您可能会问的问题:
问)为什么我会将成员变量放入@interface
?
A)你不太可能。它会将它暴露给子类,但通常希望这样做是一个设计缺陷。但是,在过去,由于旧的Objective-C运行时的工作原因,您必须将所有成员变量放入@interface
。因此,较旧的代码和陷入困境的程序员有时仍会遵循这种模式。
问)为什么我要声明一个只对@implementation
可见的属性?
A)你不太可能。然而,在过去,这是创建在@interface
中不可见的成员变量的唯一方法,因此人们在短时间内完成大多数成员变量的方式也是如此。类似地,你可以声明一些东西,比如说retain
,然后使用getter / setter并假设正在进行正确的内存管理,所以它在引入ARC之前的几天就充当了一些语法糖。与之前的答案一样,因此有些人仍然通过习惯这样做,而一些代码由于年龄的原因仍然这样做。这不是你现在经常做的事情。
编辑:更好的摘要:属性调整您的班级界面。成员变量调整其实施。在面向对象的编程中,你应该把这两件事想象为完全不相交。
面向对象编程的主要目的之一就是让一群离散的演员表示"我可以做X"完全如何他们做其他人的业务。
一个属性说一个类可以做什么。成员变量是为了如何类的好处。
从语义上讲,他们完全分开了问题。
答案 2 :(得分:0)
memberStr
的第一个是实例变量或ivar。
如果您拥有所需的属性,则无需再拥有memberStr
。
@interface test()
@property (nonatomic, strong) NSString *properyStr;
@end
原因是ivar将在setter和getter方法旁边自动创建。
通过接口文件(.h)在实现文件(.m)接口中声明属性之间的唯一区别是它仅对此类是私有的。这样做有很多好处,例如你可能不想要课外的任何东西来了解它,但你希望这个属性仍然在这个类的范围内。以这种方式使用它们的一件事是当你将readonly属性声明为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)中具有该属性完全相同,它们将起作用并执行相同的操作。