OC屬性
[toc]
屬性的作用
1. 為成員變量提供訪問的接口资盅。setter和 getter 方法
@property 與 @synthsize 搭配使用禀崖,當(dāng)你沒有實現(xiàn)屬性的setter和 getter方法時竹捉,系統(tǒng)會默認幫助生成Setter getter颅崩。
-
@synthSize var = _var;
如果沒有生成set、get方法黎侈,則默認幫助生成訪問器方法灸芳。在iOS4.4以前需要搭配@property使用涝桅,4.4以后@property不需要顯示聲明@synthsize即可生成訪問器方法。
-
@dynamic var;
聲明dynamic以后將由程序員自己生成set/get方法烙样,并且如果沒有實現(xiàn)不會觸發(fā)警告冯遂,如果真沒有實現(xiàn)而又調(diào)用了該屬性,則會導(dǎo)致crash
2. 屬性修飾符
-
nonatomic/atomic
- nonatomic
- 線程不安全 多個線程可以同時對其進行訪問谒获,沒有資源保護
- 訪問速度快
- atomic
- 線程安全 在多線程中只能有一個線程對進行訪問蛤肌,會默認會setter方法加鎖(MRC環(huán)境重寫Setter方法需要設(shè)置訪問鎖)
- 訪問效率慢
- nonatomic
-
assign/weak
- assign
- 修飾基本數(shù)據(jù)類型(非指針型變量)setter方法里不會進行任何retain操作
- assign如果拿來修飾對象類型會有野指針(懸垂指針)的危險壁却。(MRC使用unsafe_unretained修飾對象類型).assign修飾對象的話,如果對象釋放了不會置為nil|
- weak
- 修飾對象類型裸准。Arc下使用 和assign的效果一致
- weak比assign優(yōu)化的一點是展东,當(dāng)對象釋放了以后可以將修飾的指針置為nil,可以有效避免野指針的行為
- assign
copy / Strong / Retain
討論copy 需要補充一下 深拷貝|淺拷貝 的知識
// 結(jié)論
// 1.容器類型的指針 copy 只會產(chǎn)生不可變對象炒俱, mutableCopy 只會產(chǎn)生可變對象 與指針本身可變性無關(guān)
// 2.容器類型的指針 copy/mutableCopy 只是對數(shù)組內(nèi)部元素指針的復(fù)制琅锻,不會去調(diào)用元素的copy方法,所以copy后新容器內(nèi)部的元素內(nèi)容是不變的向胡。
- copy
// 系統(tǒng)引用計數(shù)的默認實現(xiàn)
- (void)setName:(NSString *)newname {
if (_name != newname) {
[_name release];
_name = [newname copy];
}
}
由上可以看出:
1. copy 修飾符 會先對舊對象release,然后copy一份新對象惊完。因此會對引用計數(shù)進行+1
2. copy 修飾符的特點就是會對對象進行一次copy僵芹。
- strong
// 系統(tǒng)引用計數(shù)的默認實現(xiàn)
- (void)setName:(NSString *)newname {
if (_name != newname) {
[_name release];
_name = [newname retain];
}
}
由上可以看出: **strong 修飾符 會先對舊對象release,然后賦值并對新對象reatin小槐。也會對引用計數(shù)進行+1**
- retain
retain 是MRC時代的產(chǎn)物,retain的實現(xiàn)和strong是一樣的拇派,因此strong 也可以用于MRC下。
特別注意:對于NSArray凿跳,NSDictionary,NSString這樣的不可變對象我們需要使用copy來修飾件豌,如果使用了strong,則對象被賦值了一個可變對象的時候控嗜,不可變對象的內(nèi)容就可以發(fā)生改變了.容易造成語義的矛盾茧彤,也極有影響代碼的運行。
-
readonly/readwrite
readwrite就是可讀寫疆栏,不加這個屬性修飾符默認就是如此曾掂,所有變量都是可以讀寫的,也就是都自帶setter和getter方法壁顶,而使用readonly修飾系統(tǒng)會自動生成getter方法而不生成setter方法所以是只讀的珠洗,無法賦值。
3.另外一些標示符
-
const
NSString const *str = @"123"; NSString * const str1 = @"123"; str = @"456"; // 這句話只是把456的內(nèi)存地址分配給str str 本身是一個變量若专,但它指向的內(nèi)存是不可變的 str1 本身是一個常量许蓖,*str1 是一個變量
const 相比 宏定義define:
1. const 在編譯階段參與編譯,宏則是在預(yù)編譯階段 2. 宏不做類型檢查调衰,只是替換內(nèi)容膊爪,const 會編譯檢查類型 3. 宏可以定義函數(shù)方法代碼塊,const不行
-
static
static 修飾的變量都是在字符常量區(qū)- static 修飾全部變量
- 限制了全局變量的作用域為當(dāng)前文件內(nèi)
- static 修飾局部變量
- 讓局部變量只初始化一次
- 局部變量在程序中只有一份內(nèi)存
- 并不會改變局部變量的作用域窖式,僅僅是改變了局部變量的生命周期
- static 修飾全部變量
-
extern
對extern來說,可以理解為擴展吧,將當(dāng)前變量的作用域從一個類擴展到另一個類蚁飒。