在 Objective-C 中,我应该什么时候使用属性,什么时候应该使用实例变量



我不熟悉同时具有属性和实例变量的程序语言。
所以我不知道使用属性和实例变量的好方法。

现在我只在我的Objective-C代码中使用属性,我不使用任何实例变量。

我需要使用实例变量吗?
或者只使用属性是Objective-C的最佳实践?

@interface ViewController : UIViewController
{
    // instance variable
    @public
    int a;
}
// property
@property(nonatomic, strong) NSString *b;
@end

变量和属性之间的基本区别在于,您可以为属性赋予属性。您不能为变量提供任何属性。因此,如果您希望有任何特定行为,例如保留变量,原子访问它,在类之外访问,则应选择属性。

如果您只想访问类中的变量,并且没有特殊行为附加到该变量,则无需通过属性访问它。您可以直接使用变量本身。它还将提高性能。

与 ivar 相比,@property有一些优势:

  • 内存管理 :在幕后,它将创建一个二传手,该二传手创建具有正确内存管理的变量。这将为您省去一些麻烦,因为您可以轻松查看内存管理是如何完成的(strong/weakretain/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

此规则的例外情况是在编写初始化、释放或自定义访问器方法时

应始终直接从初始化方法中访问实例变量,因为在设置属性时,对象的其余部分可能尚未完全初始化

在此处阅读整个文档,以更好地了解该主题。

至于性能问题,对于大多数应用程序来说,收益微不足道。阅读本文以获取非常详细的说明。

最新更新