可能重複:
How does an underscore in front of a variable in a cocoa objective-c class work?iPhone伊娃命名約定
我注意到,在很多參考資料在那裏,我看到了很多的時間,變數在.h文件被命名爲_variable,然後是@在.m文件synthesize'd爲
@synthesize variable = _variable;
這是爲什麼呢?我錯過了什麼?
謝謝!
可能重複:
How does an underscore in front of a variable in a cocoa objective-c class work?iPhone伊娃命名約定
我注意到,在很多參考資料在那裏,我看到了很多的時間,變數在.h文件被命名爲_variable,然後是@在.m文件synthesize'd爲
@synthesize variable = _variable;
這是爲什麼呢?我錯過了什麼?
謝謝!
沒有共識這個。有些人喜歡用它來清晰地分離出類變量,另一些人則指出避免與傳入參數名稱衝突。即使在Apple示例代碼中,使用也是混合的。
但是,我非常喜歡不使用_
前綴,有兩個強有力的理由:
1)有些人認爲_
是「私人」的良好指標。我的意思是,沒有一個類的局部變量應該訪問沒有一個setter/getter(屬性),因此他們都是私有的 - 爲什麼不命名他們更容易閱讀和使用自動完成?參數名稱中的任何重疊都會被編譯器快速顯示出來,並且可以通過對參數(或內部變量)的更周到的命名來避免。
2)(更好的理由) - 如果在XCode中對內部類var使用「重構」,其名稱與訪問它的屬性相同,則屬性和合成語句也將被重命名。如果對以_
爲前綴的類變量使用重構,則不會更改屬性名稱 - 只是將內部名稱映射到合成映射。我幾乎不希望名稱因屬性不同而不同,從而暴露了它的訪問權限。僅憑這一點,我就不會希望使用_
作爲變量前綴,因爲能夠改變名稱只是爲了提高代碼清晰度而做的最有用的事情。
對命名方法參數的任何建議,使他們不與伊娃爾名稱衝突?對於initWith *或手動實現的屬性設置器來說,這尤其嚴重。 我已經試過「一/一個」和「新」的前綴一段時間,但它並不總是很方便(當一個名字是複數等)。 我也試着下劃線前綴參數,但是這是容易驅動代碼的讀者瘋狂,因爲蘋果和開發社區的喜好使用具有高德強調的。在某種程度上,這也適用於下劃線後綴。 – aleh 2014-03-28 14:40:52
這些天,我用「\ _」的前綴爲所有內部類瓦爾(相反,我知道!),因爲我只用性能使用他們 - 因爲屬性自動創建的ivars _作爲前綴我堅持這一點。重構對屬性起作用,而屬性永遠不會看到名稱,因此「\ _」並不重要。它也消除了你有的重疊問題。我會編輯這個答案,以反映我在某個時候的新思想。 – 2014-03-28 15:28:06
我明白了。我仍然個人猶豫通過屬性訪問我自己的ivars(例如更像_ivar/ivar vs self。ivar):不喜歡擁有公共可寫屬性或者將只讀屬性重新聲明爲在.m中可寫。但正如你所說,沒有共識:) – aleh 2014-03-31 09:44:15
這是純粹的約定。我想它的常見的,因爲當你一個getter方法調用是這樣的:
[myObject variable]
你實際上是調用一個方法,而不是直接訪問的變量。前面的_表明你正在談論一個變量。就我個人而言,我覺得這種語法煩人和分心。我覺得沒有必要,但你是對的,它確實出現在這裏和那裏。
有時候人們使用mVarName(C++),而在Obj-c中,風格似乎是_varName。 你可以有一個問題,想象你的一個函數的參數是... set:(int)x - 但 - 你有一個名爲x的iVar ...好吧,你會讓編譯器哭這樣的東西 - 更不用說它的混亂。
m,_,無論幫助顯示什麼是類的成員屬性。
-(void) set:(int)x
{
x = x; // x is an ivar! heh
}
VS
-(void) set:(int)x
{
_x = x; // ahh I see!
}
使用語法是爲了更清楚的是,伊娃和財產是不同的東西的選項。
要在類的外部編碼,因爲它使用屬性沒有區別。
對於類本身的實現中的代碼,它可以使它更清楚何時使用ivar與屬性。
例如,假設我們有一個NSNumber對象伊娃/屬性:
@interface MyClass : NSObject {
NSNumber *num;
}
@property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
@end
@implementation MyClass
@synthesize num;
- (void)doSomething {
// set the property, num is properly retained
self.num = [NSNumber numberWithInteger:1];
// accidentally set the ivar, num is NOT retained
num = [NSNumber numberWithInteger:2];
}
@end
現在使用不同的名稱爲伊娃和財產:
@interface MyClass : NSObject {
NSNumber *i_num;
}
@property (nonatomic, retain) NSNumber *num;
- (void)doSomething;
@end
@implementation MyClass
@synthesize num = i_num;
- (void)doSomething {
// set the property, num is properly retained
self.num = [NSNumber numberWithInteger:1];
// compiler error, there is no ivar named "num"
num = [NSNumber numberWithInteger:2];
// set the ivar, so it needs to be a retained object
i_num = [[NSNumber alloc] initWithInteger:3];
}
@end
我不喜歡用「_」前綴,因爲蘋果並堅持使用它。通過避免前綴,我有更大的信心,當我擴展可可觸摸類時,我的ivars不會與Apple發生碰撞。由於我們無法訪問基類的源,所以這是我知道的避免意外重用現有私有ivars的唯一方法。
就像開頭
方法名「_」,單下劃線,保留給蘋果使用。
以前的答案是缺少這背後的歷史。在Objective-C 2.0之前,沒有任何屬性。所以,你必須與實例變量像這樣的對象:
@interface MyObject: NSObject {
NSArray *myArray;
}
@end
但你怎麼會從其他對象訪問它們?解決方案是製作二傳手和獲得者。但是爲了避免混淆,他們會做這樣的:
@interface MyObject: NSObject {
NSArray *_myArray;
}
- (NSArray *)myArray;
- (void)setMyArray:(NSArray *)myArray;
@end
的_
用於實例變量_myArray
和方法-myArray
之間清理混亂。
我不知道如何保持沒有下劃線的伊娃名稱會與myArray方法名稱混淆。至少不是由編譯器。調用一個方法[obj myArray]或引用它的選擇器@selector(myArray)總是不同於引用它的ivar(obj-> myArray或簡單的myArray或self> myArray從自己的方法)。 – aleh 2014-03-28 14:29:38
當你在一個類的實例方法中時,它更多。意外寫入'myArray = @ [@「A」,@「B」,@「C」];''而不是'myArray = @ [@「A」,@「B」,@「C」]; '。 – 2014-03-29 16:02:34
好的,我明白了。我想你的意思是,當'self.myArray = ...'的含義時,錯誤輸入'myArray = ...'會更容易。 – aleh 2014-03-31 09:49:17
我的選擇,下面Google,簡直是追加下劃線,並明確地合成(即使我重新實現):
@synthesize varName=varName_;
如果我看到結尾下劃線的init...
,dealloc
的訪問之外,或者我知道有什麼可疑的。
我見過'ivar_'用於代替'_ivar'還可以,但我真的不能形成,除了他們看起來更好地爲他們的說法... – 2012-02-20 00:03:10