在Objective-C中引入了屬性這個概念,固然了這東西並非Objective-C獨創並且獨有的特性,例如C#裏邊也有屬性的概念,所以學過C#的朋友應該很容易就掌握Objective-C中的屬性這個知識點。 java
在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的具體行爲。 線程
要在Objective中使用Property,那麼咱們得分兩步走:聲明它而後定義它。 設計
咱們能夠經過關鍵字@property來聲明屬性,並且屬性的聲明能夠出如今類中的方法列表的任何位置,也能夠出如今協議聲明的任何位置。 指針
格式:@property(屬性集)type name; 對象
readwrite(讀寫屬性:指示編譯器生成getter和setter方法,此屬性是默認的) 繼承
readonly(只讀屬性:指示編譯器只生成getter方法)
strong:強引用,至關於retain。
weak:弱引用,至關於assign,且弱引用所指向的對象被釋放後,指向該對象的指針會被自動置爲nil.
copy:指定setter方法的參數採用深度複製到目標對象上,可是setter方法的參數必需要實現NSCopying協議(協議只是Objective-C中的叫法,即接口啦)
assign:指定setter方法中只是簡單的複製,此屬性爲默認屬性。例如對一些基礎類型的屬性能夠採用它,如int,float,NSInteger....
retain:在assign基礎上,再保留setter參數的一個引用,形成的影響是setter參數中的對象的保留計數值增長了1
此屬性適用於參數爲某一個對象的指針。如NSString*,
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;
咱們能夠自定義getter和setter的名字
eg: @property(getter=MyName,setter=setMyName) NSString* name;
這樣編譯自動生成的getter和setter方法名就會按你指定的那樣:setMyName和MyName;
咱們能夠經過@synthesize 或者@dynamic來通知編譯器按照property的聲明部分指定的條件來生成對應的getter/setter。
@synthesize 屬性名[=成員變量名]; 「[]」表示裏面的內容是可選的。。
第一種形式:不帶中括號中的內容的定義方法
eg: @interface Student:NSObject
{
NSString* name;
}
@property(nonatomic,retain) NSString* name;
@implementation Student
@synthesize name; //自動生成setName和name方法
第二種方式
在聲明部分改成:@property(nonatomic,retain)NSString* myProperty;
@implementation Student
@synthesize myProperty=name; //=name表示在合成的setMyProperty和myProperty中操做的成員變量是name;
關鍵字@dynamic其實就是告訴編譯器在運行時動態地去找setter或者getter方法。由於代碼由咱們本身實現了或經過繼承而來。(我的理解)
eg:
咱們能夠經過它在子類中改變父類中的只讀屬性。例如:
@interface A:NSObject
{
int nTmp;
}
@property(assign,readonly) int nTmp; //聲明一個只讀屬性
@interface B:A
@property(readwrite,assign) nTmp;
@implementation B
@dynamic nTmp;
-(void)setNTmp:(int)newNTmp
{
nTmp = newNTmp;
}