一直有疑问,在objective_C中声明变量会有 2种方式,今天有空和网友讨论了下,并且自己查了stackoverflew后算是稍微弄懂了一点。记录如下:
用了一段oc;会发现有2种定义变量的方式
1.在 @interface :NSObject{} 的括号中,当然NSObject 是指一个父类,可以是其他的。
形式如下:
@interface GCTurnBasedMatchHelper : NSObject { BOOL gameCenterAvailable; BOOL userAuthenticated; }
2.另外一种是直接在 @interface : NSObject{}括号之后,用 @property 去定义一个变量。
@property (assign, readonly) BOOL gameCenterAvailable;
你会发现,有人会再@interface中定义了变量后,又在 @property中重复定义相同的变量,而且很常见。
结果可能是这样:
@interface GCTurnBasedMatchHelper : NSObject { BOOL gameCenterAvailable; BOOL userAuthenticated; } @property (assign, readonly) BOOL gameCenterAvailable;
而且你可以单独在@interface中定义变量,而不用@property定义;也可以只用@property去定义,而不在@interface中定义,当然用了@property去定义,一般要在.m文件中用@synthesize去合成相应的setter,getter方法。否则会得到一个警告。当然@synthesize是可选的,但是是Apple推荐的,不用会有什么后果,我没试过,有兴趣的童鞋可以试一下。
那这两种方式有什么区别呢。
1. 只在@interface中定义变量的话,你所定义的变量只能在当前的类中访问,在其他类中是访问不了的;而用@property声明的变量可以在外部访问。
2.用了@property去声明的变量,可以使用“self.变量名”的方式去读写变量。而用@interface的方式就不可以。
3. 这里给出一个链接:http://stackoverflow.com/questions/9702258/difference-between-properties-and-variables-in-ios-header-file 里面讲到: 在括号中定义一个变量只是简单的声明了一个实例变量(实例变量应该指的成员变量)。声明(和 @synthesize)一个属性会为成员变量生成 getter 和setter方法,根据括号内的标准,在oc中经常用setter和getter 做内存管理,这是很重要的。(例如: 当一个值被赋给这个变量,对象是通过setter函数去分配,修改计数器,并最后释放的)。更高一个层次来说,这种做法也促进了封装,减少了一些不必要的代码。在@interface括号中定义一个变量并用@property 重复定义一次是很普遍的,实际上不是必要的。用@property和@synthszie就够了,因为在用@synthesize合成这个属性的读写方法时就会创建一个变量。
目前苹果(在模板中)建议的方法是这样的:
先在头文件中定义一个属性
@property int gameCenter;
然后在实现文件中 synthesize和declare成这样:
@synthesize gameCenter = __ gameCenter;
最后一行synthesize gameCenter 属性并说明了不管什么值被分配给这个属性,都会存储到_gameCenter这个变量中。 再次说明,这不是必要的,但是,这样写了之后,你能减少输入已经明确命名的变量名。
据千锋的第2节语法课课程的讲解,这样写@synthesize gameCenter = __ gameCenter;之后可以使得 @synthesize 时内部getter方法会展成
-(int)gameCenter { return _gameCenter; }
而直接写 @synthesize gameCenter;则setter函数会在内部展开成
-(int)gameCenter { return gameCenter; }
注意到:函数名和变量名是一样的。在斯坦福的课程中,白胡子教授也模糊的说道这样的同名有可能带来bug,具体什么bug他没说,我也没见过,所以还是养成这样写的习惯为好。其他语言的getter函数 一般会在变量前加 get;但oc没有,可能是为了与其他语言做区分,算是oc的特色,结果却带来这么个麻烦。