方式一:(为何要定义一个_test?下划线开头代表什么意思?在实现的时候怎么又将_test付给了test?) 方式二:(方式2跟方式1到底有何区别?) 方式三:(这种最简单了,但是这样写规范吗?) 这个成员变量定义这块儿,整的很乱,看了很多教程,一个教程一个写法,有时候教程前后还不一样。我更迷茫了,到底该如何定义成员变量?求详细解答。谢谢了。
闭关修行中......
第二第三種個人感覺是極不規範的。
第一種是比較老式的寫法,不過 NSString *_test; 這個就是多餘的了,這個是更老式的了,那時候要手寫 getter setter 因為有了 synthesize 自動屬性合成器以後,這步,Xcode已經幫你做了。 也幫你寫了預設的 getter setter 方法,有底線就是標識,這個是成元變量,以便於區分 getter setter 中的形參(局部變量)。
在 m 檔案中是可以直接對 帶下劃線的 成員變數進行賦值等操作的,但規範還是建議 使用 self.test 這樣來操作,除非你正在 setter getter 方法中,那是不能用這個。
還有Google那個 objc 程式碼風格,, 哈哈成員變數 底線在後面, test_ ,又暈了吧?我估計這個風格是為了完全區分 純成員變量,和 屬性。是說 後面有底線的這貨,就純粹是類本身自己用,沒有 getter setter,不需要給別的類訪問。
最後,早在 Xcode 4.6 起,還是更早來著,記不得了, 什麼 synthesize 根本不用寫的,Xcode 已經幫你寫了 @synthesize test = _test。
所以現在最簡潔的思路就是,如果你這個變量,是要給其他類能夠訪問到的,那麼你就直接寫個 @property 就夠了。
宣告成員變數 NSString *_test; 還有屬性合成器 @synthesize test = _test,不需要寫了,
如果你這個變量,完全不需要給類別外部訪問,那麼你就 自己宣告個 成員變數 NSString *test_; 其他別寫。此初始化的地方初始化該釋放的釋放
//----------------
發現被踩了下,純個人理解可能會有誤,如有誤望不吝請指出,多謝,
前面最後說的有些不嚴謹了~ 沒說 在 h 和 m 中的區別。 在 h 中,只有 成員變數的話雖然沒有 getter setter , 子類別還是能存取的。屬性的話就是相當於公開的。
在 m 中,都是私有了。
盡量的使用屬性而非實例變數。除了在初始化方法(init,initWithCoder:等)、dealloc方法以及自訂setter與getter方法中存取屬性合成的實例變量,其他的情況使用屬性進行存取。
好的風格:
@interface RNCSection: NSObject @property (nonatomic) NSString *headline; @end
不良的風格:
@interface RNCSection : NSObject { NSString *headline; }
當你使用@synthesize指令時,編譯器會自動為你建立一個底線_開頭的實例變量,所以不需要同時宣告實例變數和屬性的。
@interface RNCSection : NSObject { NSString *headline; } @property (nonatomic) NSString *headline; @end
好的風格:
不要使用@synthesize除非是編譯器需要。注意在@protoco協定中的@optional可選屬性必須被明確地使用@synthesize指令合成屬性。
參考:iOS應用開發最佳實務系列一:編寫高品質的Objective-C程式碼
第三種,但不全是你那樣,應該是:
#import "Test.h" @interface Test () @property (nonatomic, copy) NSString *test; @end @implementation Test @synthesize test = _test; @end
一個 Objective-C property 通常會有一個輔助 ivar。 property 可能會有一個不同於 ivar 的名字。 對於實例,你可能會有一個叫做 ivarName 的 ivar,和一個叫做 propertyName 的 property。 你可以 synthesize propertyName 給 ivarName 變量,透過:
ivarName
propertyName
@synthesize propertyName = ivarName;
關於使用底線。 在實例變數前使用下劃線這是共同約定的常用寫法,當實例方法參數和實例變數重名時,這樣做可以防止名字衝突,或編譯器警告。 底線前綴也可明確指出你正在引用一個ivar。 透過為實例變數使用底線前綴,你可以在方法參數,堆疊變數等地方自由地使用不帶底線的名稱。 但當你使用 property 時,一般你不會想讓使用者去寫一個底線,因此你通常會為一個叫做 _ivarName 實例變數取一個叫做 ivarName 的 property。 這就是為什麼你要寫成:
_ivarName
@synthesize ivarName = _ivarName;
synthesize可以是用來定義屬性,他會自動生產get/set。 個人覺得: * 如果定義的是外在可見的屬性,我覺得應該採用最簡單的方式三,理由是簡潔。 * 如果是定義內部屬性或變量,建議放到 .m活.mm檔中定義,以體現對外隱藏意思(當然不能真正隱藏)。 * 如果是值語意的內部變量,用synthesize不但沒什麼好處,還會增加運行時開銷。
最新的Xcode中 直接定義@property 就行,不用@synthesize。編譯時編譯系統會自動幫你加上。
@interface Test () @property (nonatomic, copy) NSString *test; @end
property 建議加底線。 instance variable 不加。
@interface RNCSection: NSObject
@property (nonatomic) NSString *headline;
@end
直接這樣最好,會自動產生getter setter方法
同問,我也比較暈。
用Swift吧 然後就不用糾結了
如果是.m實作中的私有變數只想別人get,不想別人set如何寫呢?
第二第三種個人感覺是極不規範的。
第一種是比較老式的寫法,不過 NSString *_test; 這個就是多餘的了,這個是更老式的了,那時候要手寫 getter setter
因為有了 synthesize 自動屬性合成器以後,這步,Xcode已經幫你做了。
也幫你寫了預設的 getter setter 方法,有底線就是標識,這個是成元變量,以便於區分 getter setter 中的形參(局部變量)。
在 m 檔案中是可以直接對 帶下劃線的 成員變數進行賦值等操作的,但規範還是建議 使用 self.test 這樣來操作,除非你正在 setter getter 方法中,那是不能用這個。
還有Google那個 objc 程式碼風格,, 哈哈成員變數 底線在後面, test_ ,又暈了吧?我估計這個風格是為了完全區分 純成員變量,和 屬性。是說 後面有底線的這貨,就純粹是類本身自己用,沒有 getter setter,不需要給別的類訪問。
最後,早在 Xcode 4.6 起,還是更早來著,記不得了, 什麼 synthesize 根本不用寫的,Xcode 已經幫你寫了 @synthesize test = _test。
所以現在最簡潔的思路就是,如果你這個變量,是要給其他類能夠訪問到的,那麼你就直接寫個 @property 就夠了。
宣告成員變數 NSString *_test; 還有屬性合成器 @synthesize test = _test,不需要寫了,
如果你這個變量,完全不需要給類別外部訪問,那麼你就 自己宣告個 成員變數 NSString *test_; 其他別寫。此初始化的地方初始化該釋放的釋放
//----------------
發現被踩了下,純個人理解可能會有誤,如有誤望不吝請指出,多謝,
前面最後說的有些不嚴謹了~ 沒說 在 h 和 m 中的區別。
在 h 中,只有 成員變數的話雖然沒有 getter setter , 子類別還是能存取的。屬性的話就是相當於公開的。
在 m 中,都是私有了。
盡量的使用屬性而非實例變數。除了在初始化方法(init,initWithCoder:等)、dealloc方法以及自訂setter與getter方法中存取屬性合成的實例變量,其他的情況使用屬性進行存取。
好的風格:
不良的風格:
當你使用@synthesize指令時,編譯器會自動為你建立一個底線_開頭的實例變量,所以不需要同時宣告實例變數和屬性的。
不良的風格:
好的風格:
不要使用@synthesize除非是編譯器需要。注意在@protoco協定中的@optional可選屬性必須被明確地使用@synthesize指令合成屬性。
參考:iOS應用開發最佳實務系列一:編寫高品質的Objective-C程式碼
規範
第三種,但不全是你那樣,應該是:
關於為什麼要用底線
一個 Objective-C property 通常會有一個輔助 ivar。
property 可能會有一個不同於 ivar 的名字。
對於實例,你可能會有一個叫做
ivarName
的 ivar,和一個叫做propertyName
的 property。你可以 synthesize
propertyName
給ivarName
變量,透過:關於使用底線。
在實例變數前使用下劃線這是共同約定的常用寫法,當實例方法參數和實例變數重名時,這樣做可以防止名字衝突,或編譯器警告。
底線前綴也可明確指出你正在引用一個ivar。
透過為實例變數使用底線前綴,你可以在方法參數,堆疊變數等地方自由地使用不帶底線的名稱。
但當你使用 property 時,一般你不會想讓使用者去寫一個底線,因此你通常會為一個叫做
_ivarName
實例變數取一個叫做ivarName
的 property。這就是為什麼你要寫成:
synthesize可以是用來定義屬性,他會自動生產get/set。
個人覺得:
* 如果定義的是外在可見的屬性,我覺得應該採用最簡單的方式三,理由是簡潔。
* 如果是定義內部屬性或變量,建議放到 .m活.mm檔中定義,以體現對外隱藏意思(當然不能真正隱藏)。
* 如果是值語意的內部變量,用synthesize不但沒什麼好處,還會增加運行時開銷。
最新的Xcode中 直接定義@property 就行,不用@synthesize。編譯時編譯系統會自動幫你加上。
property 建議加底線。 instance variable 不加。
@interface RNCSection: NSObject
@property (nonatomic) NSString *headline;
@end
直接這樣最好,會自動產生getter setter方法
同問,我也比較暈。
用Swift吧 然後就不用糾結了
如果是.m實作中的私有變數只想別人get,不想別人set如何寫呢?