iOS -知識梳理(property關鍵字 copy-mutableCopy區別)
atomic :
原子操作,預設屬性,setter方法會變成下面的樣子
{lock}
if (_a != a) {
[_a release];
_a = [a retain];
}
{unlock}
但是該關鍵字不能保證該變數的執行緒安全,只是對getter 和 setter方法進行了加鎖操作,避免多個執行緒同時操作產生錯誤資料。
例如@property(acomic) NSMutableArray * values; 當values執行 addObject: ,removeObject的時候依然不是執行緒安全的。
a
nonatomic
跟atomic相反,不加鎖。
assign:
預設屬性,用於基本資料型別(例如:CGFloat, NSInteger, BOOL)
weak:
弱引用,用於修飾物件,其值會在物件被釋放後自動設定為nil。通常用於解決迴圈引用問題,例如delegate。
原理:
runtime維護了一個weak表,其實是一個hash表,key是所指物件的地址,value是weak指標的地址陣列。
分為三步:
1、初始化時,runtime呼叫objc_initWeak函式初始化一個weak指標指向物件地址。
2、新增引用,objc_initWeak函式會呼叫objc_storeWeak函式,更新指標指向,建立對應的弱引用表
3、釋放時,clearDeallocating函式根據物件地址獲取weak指標陣列並遍歷置nil,然後從weak表移除,最後清理物件。
strong:
強引用,預設屬性,修飾物件,物件被強引用時不會被釋放
retain
- (void)setA:(id)a
{
if(_a != a){
[_a release];
_a = [a retain];
}
}
對新物件引用計數加1,並對舊物件release
copy
- (void)setA:(id)a
{
if(_a != a){
[_a release];
_a = [a copy];
}
}
表示重新建立一個引用計數為1的物件,並對舊物件release
readwrite
預設屬性,表示可以讀寫,自動生成getter, setter方法
readonly
只讀,只會生成getter方法
setter
指定生成setter方法的名字
getter
指定getter方法的名字
nonnull
表示物件可以是NULL / nil
nullable
表示物件不能為空
總結一下 預設屬性有 atomic 、 assign、 readwrite
接下來補充一下 copy 和 mutable copy
首先來說系統的類
1> NSString、 NSArray等不可變物件 copy不會生成新物件,
mutableCopy會生成新物件並會變成可變物件,例如NSArray會變成NSMutableArray
2> NSMutableArray等可變物件, copy會產生新物件,並且是不可變物件 例如NSMutableArray 變成 NSArray
mutableCopy還是會產生新物件。
再說自定義的類 例如 Person 、Dog
自定義的類 例項化物件要想能拷貝 必須實現copyWithZone: 和 mutableCopyWithZone:
1 偽裝實現
- (id)copyWithZone:(NSZone *)zone
{
return self;
}
這種實現方式沒有開闢空間 、會使原物件引用+1
2.淺拷貝
- (id)copyWithZone:(NSZone *)zone
{
Person * newPerson = [[Person allocWithZone:zone] init];
newPerson.name = self.name;
return newPerson
}
這種實現方式會建立新的物件,但是新物件例項變數不會建立,比如newPerson.name 跟 oldPerson.name 指向同一處地址。
3.深拷貝
- (id)copyWithZone:(NSZone *)zone
{
Person * newPerson = [[Person allocWithZone:zone] init];
newPerson.name = [self.name mutableCopy];
return newPerson
}
這種實現會建立新的物件,並且物件實力變數也會建立新的
mutableCopyWithZone 跟 copyWithZone:一樣,關鍵在於內部實現的方式,通常copyWithZone:實現淺拷貝,
mutableCopyWithZone實現深拷貝