在Objective-C中,何时应该使用属性,何时应该使用实例变量?

时间:2012-06-06 06:15:53

标签: iphone objective-c ios properties

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

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

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

@interface ViewController : UIViewController
{
    // instance variable
    @public
    int a;
}

// property
@property(nonatomic, strong) NSString *b;

@end

7 个答案:

答案 0 :(得分:7)

变量和属性之间的基本区别在于,您可以为属性赋予属性。您不能将任何属性赋予变量。 所以,如果你希望有任何特定的行为,比如保留变量,以原子方式访问它,可以访问类,那么你应该选择属性。

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

答案 1 :(得分:5)

@property对ivar有一些优势:

  • 内存管理:在幕后,它将创建一个setter,用正确的内存管理创建变量。它会为您节省一些麻烦,因为您可以轻松查看内存管理的完成情况(strong / weakretain / copy / { {1}})。

  • 来自其他课程的辅助功能:如果您在.h中声明assign而在.m中声明@property,则您的ivar将是公共可读和可写的。您可以使用privat类扩展来阻止此操作。您甚至可以声明@synthesize public @property并通过privat类扩展在内部readonly声明它们。 例如:私人财产

readwrite
  • 自定义getter和setter :如果您愿意,您仍然可以编写自定义getter和setter,您甚至可以只编写一个getter或setter并让另一个自动 // [In the implementation file] @interface MyClass () @property (nonatomic, retain) NSMutableArray* someData; // private!! @end @implementation MyClass @synthesize someData @end 。你可以将自定义逻辑编写到这样的getter和setter中,例如您可以在@synthesize更改后重新加载tableview。

  • 自动键值观察(KVO)兼容:如果您使用或计划使用KVO,您只需通过声明属性即可免费获得。没有其他事情需要做!

  • 点符号:如果您拥有@property,则可以通过点表示法访问getter和setter。

@property
  • 如果你需要你iVar公开,写一个 self.myIvar = (id) someThing; [array addObject:self.myIvar]; 比写一个iVar的getter和setter更简单

  • 使用@property,您无需在iVar中声明(在iOS和64位Mac Os X应用程序中)。您可以通过@property

  • 来完成
@synthesize

答案 2 :(得分:4)

到处使用属性。甚至不要声明实例变量,而是像下面这样合成它们:@synthesize myProperty = _myProperty,以便将它们与属性名称区分开来。属性也是处理内存管理的好方法。您必须使用合成实例变量的唯一位置是dealloc方法 这些物业的优点很多:
  - 访问器方法定义了如何获取和设置实例变量的值   - 您可以自定义访问者方法(例如,懒惰实例化ivar或在设置新值setNeedsDisplay时执行某些操作。)   - 设置新值时,您无法处理内存管理 - 设置者负责释放/保留(取决于您如何声明属性 - retain / copy / assign / strong
  - 一些具有atomic / nonatomic属性的多线程内容   - 使用属性时,您可以利用KVO   - 至少,但不是最后 - 如果每次调用吸气剂或定位器时都不关心性能问题......

答案 3 :(得分:2)

@property是一个实例变量,它已经应用了一些语义糖,以帮助将它暴露给外界(通常),并帮助避免编写样板代码来获取和设置它。

答案 4 :(得分:0)

虽然属性通常是在你需要访问类之外的某个变量时产生的,但是在get C中,但是在目标C中,另外需要make属性是内存管理在编译器端进行,所以如果你是使用某个对象,而不是原始数据类型,然后你应该使用属性并合成它,然后如果你使用手动引用计数,则在dealloc中释放。但同样主要的目标是使它能够访问类外的一些iVar,比如将参数从一个类传递给其他类等。

答案 5 :(得分:0)

如果您@synthesize @property,您将可以访问get和set方法,这非常方便。您还可以定义setter的行为(保留,赋值,复制),如果它是非原子的或原子的,并且它是只读的。如果您没有指定任何内容(也就是说您没有合成属性),默认情况下,ivar将不会在类外显示,但您可以使用@public来实现此目的。从逻辑上讲,您也可以将其定义为@private@protected

通常我@synthesize一个@property,因为我想从课堂外访问ivar,也因为我想要一个getter和setter方法。

答案 6 :(得分:0)

一般意见是您应尽可能使用属性。如果您仍有疑问,请参阅Apple的建议:

  

通常,即使您从自己的实现中访问对象的属性,也应该使用访问器方法或点语法进行属性访问,在这种情况下,您应该使用self

...

  

此规则的例外是编写初始化,释放或自定义访问器方法

...

  

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

阅读整篇文档here,以便更好地了解该主题。

至于性能问题,对于大多数应用而言,收益微不足道。请阅读this以获取详细说明。