iOS的可變數組的執行copy操作後,添加元素出現crash

前要

copy這個屬性,相信我們用的很多的吧,尤其集合類用的比較多,我們一般都會用到就是NSArray,NSMutableArray,NSString,NSMutableString等等,copy分爲深拷貝和淺拷貝,深拷貝就是拷貝里面的內容(完全新的對象),淺拷貝只是拷貝對象地址(一樣地址)。@property (copy, nonatomic) NSMutableArray *tempArray;一般都是這麼寫,然後使用懶加載的方式給這個實例變量進行初始化,但是我使用set方法直接賦值self.tempArray = [NSMutableArray array];然後數組添加元素的時候,就會出現crash。


原因分析

首先既然添加數組的時候crash,會不會是數組沒有初始化或者數組不是可變數組的問題呢,以下是我的截圖:
這裏寫圖片描述
可以看出,執行了self.tempArray = [NSMutableArray array];之後,數組變成了不可變的數組,我們添加元素的話肯定有問題了呀,肯定會crash。肯定很多的why???我用的可變數組初始化的呀,爲什麼變成了不可變數組。其實我們換一種方式來解讀一下
這裏寫圖片描述
這裏寫圖片描述
我們看出來了吧,我只是把[NSMutableArray array]執行了copy操作,但是one卻變成了不可變數組了,那麼我們再來看看mutableCopy會是什麼結果。
這裏寫圖片描述
這裏寫圖片描述
是個可變數組。
再回頭看tempArray的屬性,是copy屬性,這就必然會執行copy操作,然後重新生成了一個新的對象賦值給tempArray,又因爲OC是動態語言,只有在執行的時候才知道是什麼類型的對象,爲什麼懶加載就可以避免了這種crash。

- (NSMutableArray *)tempArray{

    if (_tempArray) {
        _tempArray = [NSMutableArray array];
    }
    return _tempArray;
}

我們看出來使用的tempArray的實例變量,實例變量是系統幫你生成的,不會存在屬性那樣的copy的屬性,所以不會直接執行copy操作,把可變數組變成不可變數組,實例變量的自然也是可變的。


總結

copy證明可以修飾可變數組,但是會執行copy方法,生成的是個不可變的數組,所以只需要使用實例變量就可以完美解決了,也是常說的使用懶加載的模式來初始化數組對象,其實證明用retainstrong修飾的話,self.tempArray = [NSMutableArray array];這個方法生成的對象也是可變數組。retain引用計數+1;strong也就是強引用一次

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章