1. 程式人生 > >iOS -知識梳理(property關鍵字 copy-mutableCopy區別)

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

comic 只是保證提供一個完整的value 不保證執行緒安全,但是會比【nonatomic】更加消耗系統資源,使用的時候要斟酌

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實現深拷貝