1
 @interface RandomObject : NSObject
 {
  NSString* someObject; // I know I don't have to explicitly declare. Just to clarify my point. 
 }
 @property (nonatomic, strong) NSString *someObject;
 @end

 @implementation RandomObject 
 @synthesize someObject;
 @end

鉴于上面的代码并使用了 Xcode 4.3(因此,没有自动合成),这是我的问题。

property/synthesize 将为 someObject 创建访问器,即 getter 和 setter。所以如果我想给 someObject 赋值,我可以这样做。

 self.someObject = @"Tomato"; // [self setSomeObject: @"Tomato"];

如果我的理解是正确的,self 会将 @"Tomato" 发送给 setSomeObject 方法。但是如果你这样做呢?

 someObject = @"Tomato"; // or maybe _someObject = @"Tomato" if you are doing auto-synthesizing

直接访问 iVar 对象似乎是个坏主意,但由于 someObject 是私有变量,因此在同一个类中您可以访问它,对吗?

我理解如果您想从另一个类操作 someObject ,为什么需要使用 self.someOject 。但是为什么即使你还在同一个班级,你也需要做同样的事情。为什么直接访问 iVar 是个坏主意。

4

2 回答 2

3

一般来说,访问器的优点多于缺点,我可以在任何地方使用它们。

主要问题是,您直接引用 ivar 的每个地方都是您的代码需要更改的另一个潜在地方。

例如,假设您someObject在课堂上的多个地方引用过。然后需求发生变化,现在您决定在someObject分配 的值时需要进行其他一些工作。由于您在整个类中直接访问了 ivar,因此您现在必须在分配someObject或重构的任何地方复制此新代码。如果您使用的是访问器,则只需更改一段代码

- (void)setSomeObject:(id)anObject
{
  if (anObject != someObject) {
    someObject = anObject;
    [self doSomeWork];
  }
}

您可能会遇到与 getter 相同的问题 - 假设您存储了一个对象数组someObjects- 这很好用,但后来您决定实际上不需要存储someObjects,因为它可以从其他值动态计算。如果您在任何地方都直接访问了 ivar,那么这将成为一件大事。如果您坚持someObject在 getter 后面进行抽象,那么您现在要做的就是

- (NSArray *)someObjects
{
   return [self calculateSomeObjects];
}

这正是非 ARC 代码的想法,它将 ivar 的内存管理放在一个地方(在访问器之后),这样您就不必在代码中乱扔重复的代码。

于 2013-04-15T10:10:00.147 回答
2

该属性不仅仅是将一个对象分配给 ivar。

如果您不使用 ARC,该属性将自动生成保留/释放代码来处理内存管理。只是调用someObject = @"Tomato"会造成内存泄漏(如果分配了 someObject)

如果您的属性是atomic,则该属性将提供线程安全,而访问 ivar 将不是线程安全的。

有关自动生成的属性代码的示例,请参阅https://stackoverflow.com/a/589348/1597531

于 2013-04-15T09:59:01.877 回答