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

时间:2014-07-23 09:12:11

标签: ios objective-c

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

test.h

@interface test : NSObject

@end 

test.m

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

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

3 个答案:

答案 0 :(得分:1)

properyStr将自动生成getter和setter。

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

- (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)中具有该属性完全相同,它们将起作用并执行相同的操作。