我不熟悉同时具有属性和实例变量的程序语言。
所以我不知道使用属性和实例变量的好方法。
现在我只在我的Objective-C代码中使用属性,我不使用任何实例变量。
我需要使用实例变量吗?
或者只使用属性是Objective-C的最佳实践?
@interface ViewController : UIViewController
{
// instance variable
@public
int a;
}
// property
@property(nonatomic, strong) NSString *b;
@end
变量和属性之间的基本区别在于,您可以为属性赋予属性。您不能为变量提供任何属性。因此,如果您希望有任何特定行为,例如保留变量,原子访问它,在类之外访问,则应选择属性。
如果您只想访问类中的变量,并且没有特殊行为附加到该变量,则无需通过属性访问它。您可以直接使用变量本身。它还将提高性能。
与 ivar 相比,@property
有一些优势:
-
内存管理 :在幕后,它将创建一个二传手,该二传手创建具有正确内存管理的变量。这将为您省去一些麻烦,因为您可以轻松查看内存管理是如何完成的(
strong
/weak
和retain
/copy
/assign
)。 -
其他类的可访问性:如果您在 .h 中声明您的
@property
并在 .m 中@synthesize
它,则 ivar 将是公共可读和可写的。您可以通过私有类扩展来防止这种情况。您甚至可以声明一个@property
公共readonly
,并通过私有类扩展在内部readwrite
声明它们。例如:私有财产
// [In the implementation file]
@interface MyClass ()
@property (nonatomic, retain) NSMutableArray* someData; // private!!
@end
@implementation MyClass @synthesize someData
@end
- 自定义 getter 和 setter:如果您愿意,您仍然可以编写自定义 getter 和 setter,
您甚至可以只编写一个 getter 或 setter,让另一个自动
@synthesize
。您可以将自定义逻辑写入这样的 getter 和 setter 中,例如,您可以在@property
更改后重新加载表视图。符合自动键值观察(KVO)标准:如果您使用或计划使用KVO,则基本上只需声明属性即可免费获得它。不需要做任何其他事情!
点表示法:如果您有
@property
,您可以通过点表示法访问 getter 和 setter 。
self.myIvar = (id) someThing;
[array addObject:self.myIvar];
如果你需要iVar公开,那么写一个
@property
比为iVar写一个getter和setter更简单
。使用
@property
,您无需在 iVar 中声明(在 iOS 和 64 位 Mac Os X 应用程序中)。您可以通过以下@synthesize
进行操作:
@synthesize myiVar = _myIvar;
在任何地方使用属性。甚至不要声明实例变量,而是像这样合成它们:@synthesize myProperty = _myProperty
以便将它们与属性名称区分开来。属性也是处理内存管理的好方法。必须使用合成实例变量的唯一位置是在 dealloc
方法中。
属性的优点很多:
- 访问器方法定义如何获取和设置实例变量的值。
- 您可以自定义访问器方法(例如,在设置新值(如 setNeedsDisplay
)时延迟实例化 ivar 或执行某些操作。
- 设置新值时无法应对内存管理 - setter 负责释放/保留(取决于您声明属性的方式 - retain
/copy
/assign
/strong
.
- 一些具有atomic
/nonatomic
属性
的多线程内容 - 您可以使用
属性时利用KVO
- 至少,但不是最后 - 如果您担心每次调用 getter 或 setter 时都不必担心性能问题......
@property
是一个实例变量,它应用了一些语义糖,以帮助将其公开给外界(通常),并帮助避免编写样板代码来获取和设置它。
通常是在你需要访问类之外的某个变量时创建的,这意味着getter n setter,但在目标C中,make 属性的另一个需求是内存管理在编译器端进行,所以如果你使用一些对象,而不是原始数据类型,那么你应该使用属性并合成它, ,然后如果您使用手动引用计数,则在 Dealloc 中发布。但同样,主要目标是使属性访问类外的一些 iVar,例如将参数从一个类传递到另一个类等。
如果你@synthesize
一个@property
,你将可以访问一个get和一个set方法,这非常方便。您还可以定义资源库的行为方式(保留、分配、复制),如果它是非原子的还是原子的,如果它是只读的。如果您不指定任何内容(即不合成属性),则默认情况下,ivar 在类之外不可见,但您可以使用 @public
来实现这一点。从逻辑上讲,您还可以将它们定义为 @private
或 @protected
.
通常我@synthesize
@property
因为我想从课堂外部访问 ivar,也因为我想要一个 getter 和 setter 方法。
一般意见是,应尽可能使用属性。如果您仍然有疑问,以下是Apple的建议:
通常,即使从对象自己的实现中访问对象的属性,也应使用访问器方法或点语法进行属性访问,在这种情况下,应使用
self
。
。
此规则的例外情况是在编写初始化、释放或自定义访问器方法时
。
应始终直接从初始化方法中访问实例变量,因为在设置属性时,对象的其余部分可能尚未完全初始化
在此处阅读整个文档,以更好地了解该主题。
至于性能问题,对于大多数应用程序来说,收益微不足道。阅读本文以获取非常详细的说明。