你什么时候不想使用@synthesized实例变量?

时间:2010-12-07 20:54:28

标签: objective-c cocoa ios properties modern-runtime

在Modern Objective-C运行时中,您可以执行以下操作:

@interface MyClass : NSObject {
}
@property NSString *stringProperty;
@end

@implementation MyClass
@synthesize stringProperty;
@end

这是我对现代运行时的理解,这不仅会合成我的属性的访问器,而且还会合成实例变量本身,所以我可以在这个类的方法之一[stringProperty length];中说出它只会工作好像我已经宣布了一个实例变量。

我现在开始在我的所有代码中使用它,因为,我不得不一遍又一遍地写一遍。我听说过clang 2.0编译器,我甚至可以跳过@synthesize(但这是另一回事)。但我一直在想,这样做的一些缺点是什么?除了我的属性,我真的需要一个实例变量吗?

我知道有时候我想保留一个变量私有而不能从外部访问它(但是我通常只是在我的私有类扩展中声明属性,或者我根本不创建它的属性,如果我不需要访问器)。

有时我不想这样做吗?

5 个答案:

答案 0 :(得分:4)

可能建议不使用合成实例变量的一个可能原因是在当前版本的Xcode(3.2.5)中调试它们有点麻烦。在通过GDB运行代码时,它们似乎没有出现在实时调试器视图中,获取它们的唯一方法是通过gdb控制台,如po [0xOBJ_ADDRESS propertyName]。不如标准的非合成ivar那么好。

也许Xcode 4解决了这个问题,但是我没有足够的经验说它(它仍然在NDA下)。

有关此SO问题的更多信息:Seeing the value of a synthesized property in the Xcode debugger when there is no backing variable

答案 1 :(得分:3)

您可能希望为单个实例变量提供许多属性,例如:

  • 用于访问以度和弧度为单位的角度值
  • 用于访问矩形和极坐标系统中的坐标

在这些情况下,您不希望合成实例变量(它已经存在)或访问器方法(您希望提供它们来进行转换)。

答案 2 :(得分:1)

任何时候你需要在类中进行转换(除非有人知道更好的方法),你需要序列化。例如,如果您有一个具有数值的类。您无法序列化整数,因此您将其存储为类中的NSNumber,但属性是整数类型。

另一个例子是,如果您在使用CoreData时按照Apple的建议进行编码。他们说你应该创建一个从NSManagedObject派生的自定义类作为托管对象的类,并为每个属性使用一个属性。那么你将使用@dynamic而不是@synthesize,并且根本不需要iVar。

答案 3 :(得分:1)

  

但是我一直在想,这样做有什么缺点?除了我的属性,我真的需要一个实例变量吗?

可能的原因:

  • 它允许您更改initdealloc中的实例变量,而不会跳过子类覆盖或KVO。
  • 该应用程序将在Mac OS X上以32位模式编译并运行。仍然有一些Intel Mac不支持64位。

我不确定第一点到底有多有效。围绕这些问题可能还有其他方法。如果你需要支持更老的Mac,第二点就是游戏结束。

答案 4 :(得分:0)

另一个原因是避免直接变量访问的快捷方式。

我尝试遵循个人编码惯例: - 对象变量:前缀为下划线'_xxx' - property:不带下划线命名'xxx'

这确保我永远不会无意中写出像

这样的东西
xxx = value;

[xxx someMessage];

我想总是使用getter / setter。

self.xxx = value;
[self.xxx someMessage];

当您对对象变量使用lazy init时,这尤其有用......