深入理解OC中的屬性
傳統(tǒng)C++類實例變量寫法
- 傳統(tǒng)C++實例變量的定義形式 可通過關(guān)鍵字 @public 、@private 、 @protected 以及 @package 等 在頭文件中的變量默認是@protected 在.m文件中的變量默認是@private
Person.h
#import <Foundation/Foundation.h>
@interface Person : NSObject
{
@public //聲明為公有變量
NSString * _name;
@private //限制為私有變量,.m中默認類型
NSString * _ID;
@protected //限制 子類訪問變量,.h中默認類型
NSString * _surname;
@package // 包內(nèi)變量,只能本框架內(nèi)使用
NSString * _house;
}
@end
以上這種傳統(tǒng)定義形式的缺點
每個變量都需要手動編寫getter和setter方法,變量太多的時候 會寫一堆getter setter方法。而oc中屬性變量的封裝出現(xiàn)就是為了減少此工作以及代碼冗余。
這種寫法屬于‘硬編碼’,對象內(nèi)部的變量定義布局已經(jīng)寫死了編譯期,編譯后不可再更改,否則會出錯,因為編譯前 被編譯器定義為距對象初始指針地址的偏移量,編譯之后變量是通過地址偏移來尋找。如果想在類中插入新的變量,那么必須要重新編譯計算每個變量的偏移量,否則就會讀取錯誤。
屬性變量封裝定義
存取方法和變量名自動合成
使用OC的屬性編譯器會嚴格生成存取方法,通過.語法訪問變量的存取方法,(編譯器會將.語法轉(zhuǎn)換成存取方法的調(diào)用)為了區(qū)分實際的變量名在前面加下劃線,另外雖然默認加下劃線 但是可以通過關(guān)鍵字@synthesize自定義實際的變量名舊版編譯器 可能 @property 和@synthesize 是成對出現(xiàn) 因為以前不不會自動生成 setter getter方法
@dynamic 禁止自動生成 存取方法
通過@property 后的括號內(nèi)也可以進行限制
#import <Foundation/Foundation.h>
@interface Person2 : NSObject
//只讀
@property (nonatomic,copy,readonly) NSString *name1;
@end
5.類主要的屬性參數(shù)
| 原子性語義 | atomic 、 nonatomic |
|---|---|
| 讀寫語義 | readwrite、readonly 、getter、setter |
| 內(nèi)存管理語義 | assing 、weak 、unsafe_unretained、retain、strong 、copy |
atomic 、nonatomic :原子性和非原子性。原子性是數(shù)據(jù)庫原理里面的一個概念,ACID中的第一個。在多線程中同一個變量可能被多個線程訪問甚至更改,進而造成數(shù)據(jù)污染,因此為了安全,OC中默認是原子性(atomic),即會對setter方法加鎖,相應(yīng)的也會付出維護原子性(數(shù)據(jù)加鎖解鎖)的系統(tǒng)資源代價。應(yīng)用中如果不是多線程通訊變成,那么還是用nonatomic來修飾變量的,不會對setter方法加鎖,以提高多線程并發(fā)訪問時的性能。
readonly 、readwrite :readonly表示變量只讀,只有g(shù)et方法 沒有set方法 ; readwrite既有g(shù)et方法,也有set方法 ;可以直接 getter< gettername >,setter= < settername >;可以選擇性地在括號里直接指定存取方法的方法名
assing: 基本數(shù)據(jù)類型修飾,不會增加對象引用計數(shù) ;修飾:NSInteger 、int、float、double 、char 等 也可以修飾對指針的弱引用。
weak: 修飾弱引用,不增加引用計數(shù),主要用于避免循環(huán)引用,和strong/retain對應(yīng),功能是上和assing一樣 ,不同的weak修飾的對象消失后會自動將指針置位nil,防止‘懸掛指針’
unsafe_unretained: 不常用,不安全的,它修飾的不會被編譯器進行內(nèi)存管理,既不是強引用也不是弱引用,生成對象就立刻被釋放掉了,出現(xiàn)了所謂的‘懸掛指針’。
retain:通常用于引用類型,是為了持有對象,聲明強引用,將指針本來指向的舊的引用對象釋放掉,然后將指針指向新的引用對象,同時將新對象的索引計數(shù)加1。
strong 原理和retain類似,只不過在使用ARC自動引用計數(shù)時,用strong代替 retain.
copy:建立一個和新對象內(nèi)容相同的對象相同且索引計數(shù)為 1的對象,指針指向這個新對象