IOS，objective_C中用@interface和 @property 方式声明变量的区别

转帖请在开头处注明文章链接，请支持原创。

一直有疑问，在objective_C中声明变量会有 2种方式，今天有空和网友讨论了下，并且自己查了stackoverflew后算是稍微弄懂了一点。记录如下：

用了一段oc；会发现有2种定义变量的方式

1.在  @interface :NSObject{} 的括号中，当然NSObject 是指一个父类，可以是其他的。

形式如下：

1 @interface GCTurnBasedMatchHelper : NSObject {
2 BOOL gameCenterAvailable;
3 BOOL userAuthenticated;
4 }

2.另外一种是直接在 @interface : NSObject{}括号之后，用 @property 去定义一个变量。

1 @property (assign, readonly) BOOL gameCenterAvailable;

你会发现，有人会再@interface中定义了变量后，又在 @property中重复定义相同的变量，而且很常见。

结果可能是这样：

1 @interface GCTurnBasedMatchHelper : NSObject {
2 BOOL gameCenterAvailable;
3 BOOL userAuthenticated;
4 }
5
6 @property (assign, readonly) BOOL gameCenterAvailable;

而且你可以单独在@interface中定义变量，而不用@property定义；也可以只用@property去定义，而不在@interface中定义，当然用了@property去定义，一般要在.m文件中用@synthsize去合成相应的setter，getter方法。否则会得到一个警告。当然@synthsize是可选的，但是是Apple推荐的，不用会有什么后果，我没试过，有兴趣的童鞋可以试一下。

那这两种方式有什么区别呢。

1. 只在@interface中定义变量的话，你所定义的变量只能在当前的类中访问，在其他类中是访问不了的；而用@property声明的变量可以在外部访问。

2.用了@property去声明的变量，可以使用“self.变量名”的方式去读写变量。而用@interface的方式就不可以。

Defining the variables in the brackets simply declares them instance variables.

Declaring (and synthesizing) a property generates getters and setters for the instance variable, according to the criteria within the parenthesis. This is particularly important in Objective-C because it is often by way of getters and setters that memory is managed (e.g., when a value is assigned to an ivar, it is by way of the setter that the object assigned is retained and ultimately released). Beyond a memory management strategy, the practice also promotes encapsulation and reduces the amount of trivial code that would otherwise be required.

It is very common to declare an ivar in brackets and then an associated property (as in your example), but that isn't strictly necessary. Defining the property and synthesizing is all that's required, because synthesizing the property implicitly also creates an ivar.

The approach currently suggested by Apple (in templates) is:

-Define property in header file, e.g.:

1 @property int gameCenter;

Then synthesize & declare ivar in implementation:

1 @synthesize gameCenter = __ gameCenter;

The last line synthesizes the gameCenter property and asserts that whatever value is assigned to the property will be stored in the __gameCenter ivar. Again, this isn't necessary, but by defining the ivar next to the synthesizer, you are reducing the locations where you have to type the name of the ivar while still explicitly naming it.

最后一句的意思you are reducing the locations where you have to type the name of the ivar while still explicitly naming it .不好翻。

据千锋的第2节语法课课程的讲解，这样写之后可以使得 @synthsize 时内部getter方法会展成

1 -(int)gameCenter
2 {
3    return  _gameCenter;
4 }

而直接写  @synthsize  gameCenter；

setter函数会在内部展开成

1 -(int)gameCenter
2 {
3    return  gameCenter;
4 }

注意到：函数名和变量名是一样的。在斯坦福的课程中，白胡子教授也模糊的说道这样的同名有可能带来bug，具体什么bug他没说，我也没见过，所以还是养成这样写的习惯为好。其他语言的getter函数  一般会在变量前加 get；但oc没有，可能是为了与其他语言做区分，算是oc的特色，结果却带来这么个麻烦。

posted @ 2012-07-20 16:27  yessir  阅读(20763)  评论(3编辑  收藏