Objective-C之Property

 在Objective-C中引入了屬性這個概念,固然了這東西並非Objective-C獨創並且獨有的特性,例如C#裏邊也有屬性的概念,所以學過C#的朋友應該很容易就掌握Objective-C中的屬性這個知識點。 java

    1 OverView

    在java中,咱們可能常常經過getter/setter來訪問一個對象的成員變量,爲何不直接訪問對象內部的成員變量了,這樣不是更簡單嗎?由於經過getter/setter的這種模式來間接地訪問對象的成員變量,符合了類的封裝性的原則。這就好像汽車同樣,你不是直接操做汽車的引擎、油門閥、制動器來駕駛汽車,由於這些東西(成員變量)都被汽車(類)的設計者封裝起來了,不直接向外界暴露,而是經過提供諸如像方向盤、剎車的踏板、油門踏板(getter/setter)這樣的接口來供外界使用,這樣就隱藏了類內部的一些實現細節。。 安全

    既然寫getter/setter方法有這麼多好處,好吧,那咱們之後設計每一個類都這樣作,結果悲催了,由於有一天公司叫你設計一個類,而那個類有10W個成員變量,這就意味着你要寫10W對getter/setter對(固然了現實中可能不存在這樣子的極限狀況)。想一想都以爲好蛋疼。好吧,對於這樣中狀況,Objectiv-C的設計團隊隆重地在其語言特性中提供了Property的機制,以減輕咱們的工做量,同時也使得代碼變得更簡潔。 多線程

    Objective-C教導咱們:你要是想用這種機制來偷懶,好吧,你必須提供如下信息才能夠哦: atom

  1、屬性的類型和名稱(廢話,否則編譯器腫麼自動幫你生成getter/setter) .net

  2、指頂Property的屬性,以控制生成getter/setter的具體行爲。 線程

2 Property的聲明和實現

要在Objective中使用Property,那麼咱們得分兩步走:聲明它而後定義它。 設計

2.1 Property的聲明

咱們能夠經過關鍵字@property來聲明屬性,並且屬性的聲明能夠出如今類中的方法列表的任何位置,也能夠出如今協議聲明的任何位置。 指針

格式:@property(屬性集)type name; 對象

2.2 屬性集

2.2.1 讀寫性:

readwrite(讀寫屬性:指示編譯器生成getter和setter方法,此屬性是默認的) 繼承

readonly(只讀屬性:指示編譯器只生成getter方法)

2.2.2 針對setter方法的屬性

strong:強引用,至關於retain。

weak:弱引用,至關於assign,且弱引用所指向的對象被釋放後,指向該對象的指針會被自動置爲nil.

copy:指定setter方法的參數採用深度複製到目標對象上,可是setter方法的參數必需要實現NSCopying協議(協議只是Objective-C中的叫法,即接口啦)

assign:指定setter方法中只是簡單的複製,此屬性爲默認屬性。例如對一些基礎類型的屬性能夠採用它,如int,float,NSInteger....

retain:在assign基礎上,再保留setter參數的一個引用,形成的影響是setter參數中的對象的保留計數值增長了1

此屬性適用於參數爲某一個對象的指針。如NSString*,

2.2.3Atomicty即原子性,

nonatomic屬性:指定對屬性的訪問是非原子性的,默認是atomic原子性的。

atomic屬性:指定對屬性的訪問時原子性的。此屬性爲默認值

通常爲了在多線程環境中,提供健壯的屬性訪問,能夠將property的屬性指明爲atomic,這樣就不會再get的同時,也有另一個線程在對同一個property進行set操做。但這樣作雖然安全了,但犧牲了效率。魚與熊掌不可兼得呀。

若是你指定了property的屬性集爲strong、copy或者是retain,但沒有指定nonatomic,那麼在引用計數的環境中,編譯器會爲該property生成相似於以下的getter方法:

[_internal lock]

id result = [[value retian] autorelease];

[_internal unlock]

return result;

2.2.4 getter和setter屬性

咱們能夠自定義getter和setter的名字

eg: @property(getter=MyName,setter=setMyName) NSString* name;    

這樣編譯自動生成的getter和setter方法名就會按你指定的那樣:setMyName和MyName;

3 property的實現

咱們能夠經過@synthesize 或者@dynamic來通知編譯器按照property的聲明部分指定的條件來生成對應的getter/setter。

3.1 @synthesize

@synthesize 屬性名[=成員變量名]; 「[]」表示裏面的內容是可選的。。

第一種形式:不帶中括號中的內容的定義方法

eg: @interface Student:NSObject

{

    NSString* name;

}

@property(nonatomic,retain) NSString* name;

@end

@implementation Student

@synthesize name;    //自動生成setName和name方法

@end

第二種方式

在聲明部分改成:@property(nonatomic,retain)NSString* myProperty;

@implementation Student

@synthesize myProperty=name;    //=name表示在合成的setMyProperty和myProperty中操做的成員變量是name;

@end

3.2@dynamic

關鍵字@dynamic其實就是告訴編譯器在運行時動態地去找setter或者getter方法。由於代碼由咱們本身實現了或經過繼承而來。(我的理解)

eg:

3.2.1@dynamic小技巧:

咱們能夠經過它在子類中改變父類中的只讀屬性。例如:

@interface A:NSObject

{

    int nTmp;

}

@property(assign,readonly) int nTmp;        //聲明一個只讀屬性

@end

@interface B:A

@property(readwrite,assign) nTmp;          

@end

@implementation B

@dynamic nTmp;

-(void)setNTmp:(int)newNTmp

{

    nTmp = newNTmp;

}

@end

相關文章
相關標籤/搜索