轉自http://www.cnblogs.com/letmefly/archive/2012/07/20/2601338.html html
一直有疑問,在objective_C中聲明變量會有 2種方式,今天有空和網友討論了下,而且本身查了stackoverflew後算是稍微弄懂了一點。記錄以下: ios
用了一段oc;會發現有2種定義變量的方式 app
1.在 @interface :NSObject{} 的括號中,固然NSObject 是指一個父類,能夠是其餘的。 函數
形式以下: ui
1 @interface GCTurnBasedMatchHelper : NSObject {
BOOL gameCenterAvailable; 3 BOOL userAuthenticated;
}
2.另一種是直接在 @interface : NSObject{}括號以後,用 @property 去定義一個變量。 this
1 @property (assign, readonly) BOOL gameCenterAvailable;
你會發現,有人會再@interface中定義了變量後,又在 @property中重複定義相同的變量,並且很常見。 spa
結果多是這樣: .net
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推薦的,不用會有什麼後果,我沒試過,有興趣的童鞋能夠試一下。 code
那這兩種方式有什麼區別呢。 htm
1. 只在@interface中定義變量的話,你所定義的變量只能在當前的類中訪問,在其餘類中是訪問不了的;而用@property聲明的變量能夠在外部訪問。
2.用了@property去聲明的變量,能夠使用「self.變量名」的方式去讀寫變量。而用@interface的方式就不能夠。
3. 這裏給出一個連接:http://stackoverflow.com/questions/9702258/difference-between-properties-and-variables-in-ios-header-file 裏面講到: 我英語菜,簡單翻一下:
Defining the variables in the brackets simply declares them instance variables.
在括號中定義一個變量只是簡單的聲明瞭一個實例變量(實例變量應該指的成員變量)。 博主注:老外對variable 和instance variable是有不一樣理解的。因此下文中 用了一個模糊的詞 ivar。
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.
聲明(和 @synthsize)一個屬性會爲成員變量生成 getter 和setter方法,根據括號內的標準,在oc中常常用setter和getter 作內存管理,這是很重要的。(例如: 當一個值被賦給這個變量,對象是經過setter函數去分配,修改計數器,並最後釋放的)。更高一個層次來講,這種作法也促進了封裝,減小了一些沒必要要的代碼。
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.
在@interface括號中定義一個變量並用@property 重複定義一次是很廣泛的,實際上不是必要的。用@property和@synthszie就夠了,由於在用@synthsize合成這個屬性的讀寫方法時就會建立一個變量。
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:
而後在實現文件中 synthsize和declare成這樣:
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.
最後一行synthsize gameCenter 屬性並說明了無論什麼值被分配給這個屬性,都會存儲到_gameCenter這個變量中。 再次說明,這不是必要的,可是,這樣寫了以後,你能減小輸入已經明確命名的變量名。
最後一句的意思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的特點,結果卻帶來這麼個麻煩。