在cocoa中声明私有变量的最佳方法

dou*_*e07 3 cocoa properties private instance-variables

我想知道在cocoa中声明私有实例变量的建议是什么.这个问题是在iPhone上开发应用程序的背景下.

我知道至少有三种声明私有变量的方法:

  1. 使用修饰符@private在h文件的接口中声明它们:

    @interface MyClass : NSObject {  
      @private  
      NSObject * myPrivateVar;   
    }
    
    Run Code Online (Sandbox Code Playgroud)
  2. 在m文件的实现部分声明它们:

    @implementation MyClass  
    NSObject * myPrivateVar;
    
    Run Code Online (Sandbox Code Playgroud)
  3. 在m文件的接口中声明一个属性(甚至不声明变量本身):

    @interface MyClass ()  
    @property (nonatomic, retain) NSString* myPrivateVar;  
    @end  
    @implementation  
    @synthesize myPrivateVar;
    
    Run Code Online (Sandbox Code Playgroud)

到目前为止,我已广泛使用2但最近才意识到由于缺乏垃圾收集,这可能是危险的.是否存在使用该方法完全可以接受的情况?

3更合适吗?答案是否取决于对象类型(例如,mutable/immutable)?

参考资料的指针一般也赞赏使用/不使用属性的权衡.

CRD*_*CRD 5

您的三个选项具有不同的语义:

  1. 这将创建一个实例变量.没有垃圾收集,您需要retain/ release存储的对象myPrivateVar.
  2. 根本不定义实例变量.@interface在许多方法(或函数)定义的范围之外定义的变量是"全局的" - 有效的类变量(Objective-C没有特殊的语法).这样的变量由所有实例共享MyClass.
  3. 使用属性(有或没有显式声明变量)之间的区别归结为内存管理.定义与您一样retain意味着没有retain/ release当您没有垃圾收集时.

所以不要用2!如果您没有垃圾收集,选项3显然会带来好处,它提供了一些抽象措施,而不是选项1,并且成本更高 - 尽管您可能不会注意到计算密集型代码之外的差异,这些代码会大量访问变量.

2015年更新

其中垃圾收集被上面使用ARC(自动引用计数)是现在更适用(垃圾收集现在已经过时).现在还有第四种选择:

  1. 在m文件的实现部分声明它们:

    @implementation MyClass  
    {
       NSObject * myPrivateVar;
    }
    
    Run Code Online (Sandbox Code Playgroud)

    与选项(2)不同,这确实声明了一个实例变量.该变量对于实现是私有的,并且ARC内存管理是自动的.在这个和(3)[顺便说一下也不再需要@synthesize]之间的选择归结为选择和需要; 属性为您提供点语法,自定义setter和/或getter的能力,以及copy赋值时自动复制的属性,但如果您不需要这些属性,则只需使用实例变量即可.