屬性

概述

適用:Objective-C 2.0中引入了屬性(property),只適用于Mac OS X10.5以上的版本。

修飾符用法

assign修飾符用來修飾值類型和id類型(一般是delegate)的屬性,需要注意的是如果id類型的屬性的修飾符用了assign,當(dāng)你不需要這個屬性時,你必須將delegate手動置空,防止野指針產(chǎn)生,這也是為什么 delegate 一般都用 weak 修飾的原因。
weak 和 strong 是 ARC 的產(chǎn)物,分別表示弱引用類型和強引用類 型。在給 strong 修飾的屬性賦值時,會將屬性的指針指向新值的地址,同時持有這個新值(新值的引用計數(shù)被加1)。在給 weak 修飾的屬性賦值時,只是簡單地將屬性的指針指向新值的地址,不會持有新值。
retain 在 ARC 下基本等同于 strong。
copy 表示強引用,但是不會持有新值,而是拷貝一份引用計數(shù)為1的值給屬性。給這種修飾符修飾的屬性賦值時,實際上是把 新值調(diào)用 copy 方法后的返回值 賦給屬性。NSString 類型常常用 copy 修飾,就是防止修改某個對象后,對強引用這個對象的屬性造成不必要影響。
引用類型默認(rèn)的修飾符是 strong.
值類型的默認(rèn)修飾符是 assign.

原風(fēng)格

{
    float rainHandling;
    float snowHandling;
}
- (void)setRainHandling: (float) rainHanding;
- (float) rainHandling;
- (void) setSnowHandling: (float) snowHandling;
- (float) snowHandling;

屬性風(fēng)格

{
    float rainHandling;
    float snowHandling;
}
@property float ranHanding;
@property float snowHandling;

說明:@prorerty 預(yù)編譯指令的作用是自動聲明屬性的setter和getter方法。屬性的名稱不必與實例變量的名稱相同。,但大多數(shù)情況下它們是一樣的。

.m文件下的修改

@synthesize rainHandling;
@synthesize snowHandling;
@synthesize表示”創(chuàng)建了該屬性的訪問代碼“(在Xcode4.5以后的版本,可以不必使用@synthesize了)

實例變量不是必須的

需要注意頭文件中有兩個叫做rainHandling和snowHandling的實例變量(合成的setter和getter方法會用到這些變量)。如果你沒有聲明這些變量,編譯器也會聲明的。

點表達(dá)式的妙用

[tire setRainHandling:20+i];
[tire setSnowHandling:28+i];
=
tire.rainHandling = 20+i;
tire.snowHandling = 28+i;

[trie rainHandling],[trie snowHandling]
=
trie.rainHandling,trie.snowHandling

如果點表達(dá)式出現(xiàn)在了等號的左邊,該變量名稱的setter方法被調(diào)用;如果點表達(dá)式出現(xiàn)在了等號的右邊,則該變量名稱的getter方法被調(diào)用。

屬性擴展

屬性同樣適用于int、char、BOOL和struct類型。甚至可以定義一個NSRect對象的屬性。
不過對象也會帶來一些麻煩。我們在適用訪問方法對象時需要保留和釋放對象。對于某些對象的值,尤其是字符串的值,你總是會復(fù)制(-copy)它們。而對于其他對象的值,如委托,你根本不會想要保留它們。
為什么要復(fù)制對象?
你想要復(fù)制的字符串參數(shù)。一種常見的錯誤就是從用戶界面(如文本框)中獲得一個字符串,并將其作為某事物的名稱使用。文本框中的字符串通常都是可變字符串,復(fù)制該字符串可以防止因意外的變換而產(chǎn)生不利的影響。

原風(fēng)格

  - (id)init
{    
   name = [[NSString alloc] initWithString:@"Car"];
}

- (void)setName:(NSString *)newName
{
   [name release];
   name = [newName copy];
} //setName
- (NSString *)name
{
   return (name);
}//name
- (void)dealloc
{
   [name release]
}

屬性風(fēng)格

@property (copy) NSString *name;
@property (retain) Engine *engine;//engine屬性使用的只有保留和釋放特性
  • 如果copy和retain都沒有使用的話,默認(rèn)為使用assign。
  • 如果你不想保留某個變量對象,可以使用assign,這樣可以避免發(fā)生保留死循環(huán)。
  • nonatomic 可以在非多線程中使用,可以了提高訪問放的調(diào)用速度
  • 系統(tǒng)默認(rèn)為nonatomic和assign。你可以為可保留的指針(Objective-C對象)指定retain和copy特性。而其他C類型和不可保留的指定必須使用assign特性并且要手動來管理內(nèi)存。
  • 如果自己定義setter或getter方法,那么就不能使用atomic特性了,必須使用nonatomic特性。

名稱的使用

.h中
{
    NSString *appellation;
    Engine *engine;
}
@property (copy) NSString *name;
@property (retain) Engine *engine;
.m中
@synthesize name = appellation;
編譯器扔將創(chuàng)建-setName:和-name方法,但在實現(xiàn)代碼中用的卻是appellation實例變量。

只讀屬性

系統(tǒng)默認(rèn)是readwrite,假設(shè)我們不想讓任何人修改它,可以設(shè)置屬性為readonly

  • @property (readonly) float shoeSize;
    當(dāng)編譯器知道這個@property屬性是只讀的,它將只生成一個getter方法而不會生成setter方法。調(diào)用set方法會報錯,點語法也同樣。

不要變量、getter和setter方法

@dynamic 不生成任何代碼或創(chuàng)建相應(yīng)的實例變量。
創(chuàng)建一個能在運行時計算此值的訪問方法,不能set這個值。

@property (readonly) float bodyMassIndex;
- (float)bodyMassIndex;
- (float)bodyMassIndex
{
    //compute and return bodyMassIndex
}

換個名字(getter= | setter=)

@property (getter=isHidden) BOOL hidden;
它告訴編譯器生成名為isHidden的getter方法,并生成名為默認(rèn)setHidden:的setter方法

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容