【问题标题】:Why should I use @properties? [duplicate]为什么我应该使用@properties? [复制]
【发布时间】:2011-04-09 04:55:11
【问题描述】:

可能重复:
What describes @property(…) best? What's that actually good for?

如果我在我的类接口中声明一个变量,我可以在我的类的任何地方使用这个变量。太棒了。

如果我使用@property (retain) Something *myVar;,我可以使用self.myVar 访问该变量...但是,有什么区别?我应该使用一种或另一种方法有充分的理由吗?

【问题讨论】:

  • 我相信这与您是否要创建 getter/setter 方法有关,但不要引用我的话。这是可可老手的常识,我相信很快就会有人回答这个问题:)

标签: iphone objective-c ios


【解决方案1】:

简答:内存管理的封装。

更长的答案:如果你想稍后使用它,你需要建立一个对象的所有权。如果您想稍后使用它,您需要一个对它的引用来这样做,并且保存该引用的好地方是在实例变量中。

可以在每次为它分配新值时处理所有权声明(即保留和释放),但这会留下大量重复且容易出现问题的样板代码分散在整个地方,就像水果蛋糕里的樱桃。当(而不是如果)出现问题时,这种混乱非常难以调试。因此,最好将代码封装在访问器方法中,这样您就可以编写一次然后忘记它。

但访问器方法也大多是样板文件,因此我们使用@property 声明来自动创建它们,而不是手动编写它们。

编辑:Apple 的Memory Management Guide 提供了很多关于@property 生成的访问器方法在幕后做什么的详细信息。

【讨论】:

  • 所以我提到的第一种方法不会建立对象的所有权,因此我将来可能会丢失它?我想我只会对所有内容使用属性=/。最后一件事:如果我在 Dealloc 方法中使用 self.myProperty = nil (当我不再需要它时)我很好,对吧?我不用说 [self.myProperty release] 什么的?
  • 否,所有权是通过使用 +alloc、-copy 或 -mutableCopy 创建对象或通过向其发送 -retain 消息来建立的。无论您如何建立所有权,您都必须通过发送 -release 消息来放弃它。还有一个问题 - 每次为实例变量分配新值时,都需要释放旧值,并且需要确保所有这些所有权声明保持平衡。
  • 最简单的方法是避免建立所有权的创建方法,或者在必须使用它们时使用 -autorelease,并简单地让属性分配处理其余部分。
  • 常识是避免在 -dealloc 中分配属性,因为它们可能会产生副作用 - 例如,如果通过可可绑定观察属性。在 dealloc 中,你应该 [myProperty release];和 myProperty = nil; - 即绕过生成的访问器方法并直接分配给实例变量。
  • 啊,所以我也必须使用 [self.myProperty release] ......很有趣,谢谢。我也会阅读 Apple 文档 :)
【解决方案2】:

如果我使用@property(保留)Something *myVar;我可以使用 self.myVar 访问该变量...但是,有什么区别?

@property (retain) Something *myVar;

// this property declaration declares:
- (Something *)myVar;
// and 
- (void)setMyIvar:(Something *)arg;
// and is accessible by dot syntax.
// it also declares and/or documents how the ivar is managed (copy, retain, etc.)

使用中:

// direct access to the ivar. zero additional overhead (with regard to accessing the ivar)
[myVar message];

// properties used with dot syntax invoke the accessor. therefore,
[self.myVar message];
// is the same as:
[[self myVar] message];

该属性的属性还向编译器提供有关如何合成访问器的说明。

我应该使用一种或另一种方法有充分的理由吗?

在 init 和 dealloc 中,直接访问 ivar - 您对对象的 ivar 的初始化和清理感兴趣,而不关心子类。在此处使用属性也可能会引入错误或未定义的行为。

对于其他情况,即当对象处于完全构造状态时,您应该始终使用访问器以保持一致性。如果子类覆盖访问器,直接访问 ivar 可能会破坏设计。

如果您想避免这种情况,则将 ivar 设为私有并且不要为其声明属性。如果你确实为它声明了一个属性,那么记录它是私有的;在这种情况下,我通常会写 @property (retain) Something * private_myIvar;。在这种情况下,使用属性来合成 ivar 的内存管理很方便。

当 ivar 是私有的时,您可以完全访问它。直接进入或通过私有财产进入是安全的。否则,假设您必须使用访问器。

如果 myIvar 被声明为私有且仅在初始化时创建,则可以完全避免声明属性。这将减少运行时开销(如果这很关键)。消息传递开销、保留/释放周期和原子将(自然)需要更多的执行时间。因此可以绕过它来提高性能。

可见性/维护。有时,从界面中隐藏 ivar 的维护/实现要少得多。在其他情况下,ivar 是类的实现细节,不应该是公共接口的一部分。在这种情况下,请考虑将其设为私有(在 objc 中有几种方法可以实现)。

【讨论】:

    【解决方案3】:

    使用 @property 访问您的 ivars,为您执行大量释放和保留对象的重复代码。您不必使用它们。只是很多教程让刚接触该平台的人变得简单。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-07-16
      • 1970-01-01
      • 2017-11-18
      • 2014-04-13
      • 1970-01-01
      • 2012-03-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多