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