@property分為@property和@dynamic或者@synthesize:
@property
闽寡,寫在.h 文件的@interface
中,完成屬性的聲明@dynamic
或者@synthesize
歉备,寫在.m文件的@implementation
中康辑,完成屬性時實現(xiàn)@dynamic
的意思是告訴編譯器樱溉,該屬性的實例變量和存取方法由用戶自己實現(xiàn),不自動生成齐饮。
用@property聲明的NSString(或NSArray捐寥,NSDictionary)經(jīng)常使用copy關(guān)鍵字,為什么祖驱?如果改用strong關(guān)鍵字握恳,可能造成什么問題?
- 因為父類指針可以指向子類對象捺僻,使用
copy
的目的是為了讓本對象的屬性不受外界的影響乡洼,使用copy
無論傳入的是一個可變的對象還是一個不可變的對象,我本身持有的都是一個不可變的副本匕坯。- 如果使用的是
strong
束昵,那么這個屬性就有可能指向一個可變的對象,如果這個可變對象在外界被修改了葛峻,那么會影響該屬性锹雏。
//.h 文件中
@property (nonatomic) NSInteger age;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, strong) NSNUmber *number;
// .m文件中
@synthesize name = _name,age = _age, number = _number;
// 該語句不寫就是默認(rèn)自動生成的术奖,代表所有 setter 和 getter 方法的實現(xiàn)
在平時的使用中礁遵,在.h中進(jìn)行@property
后,會自動在.m中生成相對應(yīng)的@synthesize
采记。
@synthesize 的作用:
1.添加屬性對應(yīng)的成員變量
2.規(guī)定了該屬性聲明的 setter getter 方法所操作的成員變量
3.如果@synthesize 省略不寫佣耐,則自動生成對應(yīng)屬性的 setter 和 getter 方法,
默認(rèn)操作的成員變量是‘_’+屬性名
4.檢測手動實現(xiàn)了@synthesize唧龄,就會按照你的要求生成成員變量名稱并生成對應(yīng)的 setter
和 getter 方法兼砖,
如@synthesize name = _myName; 這樣成員變量就是 _myNam 了
5.在以下幾種情況下不會自動合成setter 和 getter 方法,而且也不會檢測成員變量是否存在,
也就不會幫助我們生成對應(yīng)的成員變量掖鱼,則需要我們自己添加成員變量:
1>同事重寫了 setter 和 getter 時然走;
2>重寫了只讀屬性的 getter 時;
3>使用了@dynamic時;
4>在@protocol 中定義的所有屬性戏挡;
5>在 category 中定義的所有屬性;
6>重寫的屬性晨仑,當(dāng)你在子類中重寫了父類中的屬性褐墅,你必須使用@synthesize來手動合成ivar。
關(guān)于@property的說明:
1.讀寫特性
(1)
readwrite(可讀可寫)
默認(rèn)屬性洪己,既生成 setter 方法妥凳,又生成 getter 方法
(2)readonly(只讀)
,只生成getter
方法答捕,不會生成setter
方法
(3)setter = 方法名
逝钥,給生成的setter
方法起一個其他的方法名
(4)getter = 方法名
,給生成的getter
方法起一個其他的方法名
2.原子特性
atomic(原子特性)
默認(rèn)屬性拱镐,保證線程安全艘款,也就是當(dāng)前的實例變量只能由一個線程訪問,在這個過程中有一個加鎖解鎖的過程(其實然并卵沃琅,這個操作并不能根本上保證線程的安全哗咆,還會因為加鎖解鎖的操作增加損耗。)
對于
atomic
的屬性益眉,系統(tǒng)生成的getter/setter
會保證 get晌柬、set 操作的完整性,不受其他線程影響郭脂。比如年碘,線程 A 的getter
方法運行到一半,線程 B 調(diào)用了 setter:那么線程 A 的getter
還是能得到一個完好無損的對象展鸡。
而
nonatomic
就沒有這個保證了屿衅。所以,nonatomic
的速度要比atomic
快娱颊。
不過
atomic
可并不能保證線程安全傲诵。如果線程 A 調(diào)了getter
,與此同時線程 B 箱硕、線程 C 都調(diào)了setter
——那最后線程 A get 到的值拴竹,3種都有可能:可能是 B、C set 之前原始的值剧罩,也可能是 B set 的值栓拜,也可能是 C set 的值。同時,最終這個屬性的值幕与,可能是 B set 的值挑势,也有可能是 C set 的值。
3.語義特性
(1)
assign
默認(rèn)屬性啦鸣,一般用來修飾非對象類型的屬性潮饱,但是也可以修飾對象類的屬性
(2)retain
針對于對象,會將對象的引用計數(shù)加1 诫给,MRC下的香拉,在ARC下被strong取代
(3)copy
針對于對象,將對象拷貝一份中狂,產(chǎn)生一個新的對象凫碌,多用于像NSString
,NSDictionary
胃榕,NSArray
這樣本身有可變類型的盛险。可變類型的對象不能用copy
勋又,copy
過來會是不可變類型
(4)weak
弱引用苦掘,針對于對象,不持有對象赐写,當(dāng)對象被釋放時鸟蜡,自動將對象置為nil
,用于防止循環(huán)引用挺邀。
copy與retain
copy
是建立一個相同的對象揉忘,retain
不是copy
是內(nèi)容拷貝,retain
是指針拷貝端铛。copy
是內(nèi)容的拷貝 ,對于像NSString
,的確是這樣泣矛,但是如果copy
的是一個NSArray
呢?這時只是copy
了指向array
中相對應(yīng)元素的指針.這便是所謂的"淺復(fù)制".copy
的情況:NSString *newPt = [pt copy];
此時會在堆上重新開辟一段內(nèi)存存放@"abc"
比如0X1122
內(nèi)容為@"abc"
同時會在棧上為newPt
分配空間 比如地址:0Xaacc
內(nèi)容為0X1122
因此retainCount
增加1供newPt
來管理0X1122
這段內(nèi)存;
assign與retain:
assign
: 簡單賦值禾蚕,不更改索引計數(shù)您朽;assign
的情況:NSString *newPt = [pt assing]
;
此時newPt
和pt
完全相同 地址都是0Xaaaa
內(nèi)容為0X1111
即newPt
只是pt
的別名,對任何一個操作就等于對另一個操作换淆, 因此retainCount
不需要增加哗总;
3.
assign
就是直接賦值;
4.retain
使用了引用計數(shù)倍试,retain
引起引用計數(shù)加1,release
引起引用計數(shù)減1讯屈,當(dāng)引用計數(shù)為0時,dealloc
函數(shù)被調(diào)用县习,內(nèi)存被回收涮母;
5.retain
的情況:NSString *newPt = [pt retain];
此時newPt
的地址不再為0Xaaaa
谆趾,可能為0Xaabb
但是內(nèi)容依然為0X1111
。 因此newPt
和pt
都可以管理"abc"所在的內(nèi)存叛本,因此retainCount
需要增加1 沪蓬;
readonly:
- 屬性是只讀的,默認(rèn)的標(biāo)記是讀寫来候,如果你指定了只讀跷叉,在
@implementation
中只需要一個讀取器》涂保或者如果你使用@synthesize
關(guān)鍵字性芬,也是有讀取器方法被解析
readwrite:
- 說明屬性會被當(dāng)成讀寫的,這也是默認(rèn)屬性剧防。設(shè)置器和讀取器都需要在
@implementation
中實現(xiàn)。如果使用@synthesize
關(guān)鍵字辫樱,讀取器和設(shè)置器都會被解析峭拘;
nonatomic:
- 非原子性訪問,對屬性賦值的時候不加鎖狮暑,多線程并發(fā)訪問會提高性能鸡挠。如果不加此屬性,則默認(rèn)是兩個訪問方法都為原子型事務(wù)訪問搬男;
weak and strong property (強引用和弱引用的區(qū)別):
weak
和strong
屬性只有在你打開ARC時才會被要求使用拣展,這時你是不能使用retain release autorelease
操作的,因為ARC
會自動為你做好這些操作缔逛,但是你需要在對象屬性上使用weak
和strong
,其中strong
就相當(dāng)于retain
屬性备埃,而weak
相當(dāng)于assign
。- 只有一種情況你需要使用
weak(默認(rèn)是strong)
褐奴,就是為了避免retain cycles
(就是父類中含有子類{父類retain了子類}按脚,子類中又調(diào)用了父類{子類又retain
了父類},這樣都無法release
)- 聲明為
weak
的指針敦冬,指針指向的地址一旦被釋放辅搬,這些指針都將被賦值為nil
。這樣的好處能有效的防止野指針脖旱。
ARC(Automatic Reference Counting):
- 就是代碼中自動加入了
retain/release
堪遂,原先需要手動添加的用來處理內(nèi)存管理的引用計數(shù)的代碼可以自動地由編譯器完成了。
該機(jī)能在iOS 5/ Mac OS X 10.7
開始導(dǎo)入萌庆,利用Xcode4.2
以后可以使用該特性溶褪。
strong,weak,copy 具體用法:
- 具體一點:
IBOutlet
可以為weak
,NSString
為copy
踊兜,Delegate
一般為weak
竿滨,其他的看情況佳恬。一般來說,類“內(nèi)部”的屬性設(shè)置為strong
于游,類“外部”的屬性設(shè)置為weak
毁葱。說到底就是一個歸屬權(quán)的問題。小心出現(xiàn)循環(huán)引用導(dǎo)致內(nèi)存無法釋放贰剥。
- 用
assign
聲明的delegate
倾剿,在delegate
指向的對象銷毀后,delegate
中依然會保留之前對象的地址蚌成,即delegate
變成野指針前痘。- 用
weak
聲明的delegate
,在delegate
指向的對象銷毀后担忧,delegate = nil
- 不用
ARC
的話就會看到很多retian
芹缔。- 如果你寫了
@synthesize abc = _abc
;的話瓶盛,系統(tǒng)自動幫你聲明了一個_abc
的實例變量最欠。