日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Copy修饰的NSArray

發布時間:2023/12/20 编程问答 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Copy修饰的NSArray 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

深復制與淺復制

簡單點理解,深復制,在內存中拷貝一份新的對象。 淺復制,沒有拷貝新的對象,只是一個地址的引用。 在賦值過程中深復制操作,原對象的引用計數不會增加,淺復制引用計數會加一。

copy操作和mutableCopy操作

一個類遵循NSCopying,NSMutableCopying協議并且實現相對應的初始化方法后,這個類就具有對象拷貝的能力。如果你自定義類沒有遵守協議直接調用copy/mutableCopy程序會奔潰。拷貝協議的具體使用我這里不做擴展感興趣的可以自行Google一下。有一些剛接觸iOS開發的同學認為copy操作就是淺復制,mutableCopy就是深復制,這是一個非常錯誤的理解。以下是我的一些總結:

  • 可變的集合對象 + copy 得到一個新的對象(新對象不可變)深復制
  • 可變的集合對象 + mutablecopy 得到一個新的對象(新對象可變)深復制
  • 不可變集合對象 + copy 沒有得到新的對象(地址的引用)淺復制
  • 不可變集合對象 + mutablecopy 得到一個新的對象(新對象可變)深復制 OC中集合對象NSArray、NSMutableArray、NSDictionary、NSMutableDictionary、NSSet、NSMutableSet等,另外NSString、NSMutableString也準守以上原則。實踐出真理我們來看看代碼中的效果:
NSString *str = @"abc";NSMutableString *mStr = [NSMutableString stringWithString:str];NSString *strCopy = [str copy];NSString *strMutableCopy = [str mutableCopy];NSString *mStrCopy = [mStr copy];NSString *mStrMutableCopy = [mStr mutableCopy];NSArray *arr = @[@"abc"];NSMutableArray *mArr = [NSMutableArray arrayWithArray:arr];NSArray *arrCopy = [arr copy];NSArray *arrMutableCopy = [arr mutableCopy];NSArray *mArrCopy = [mArr copy];NSArray *mArrMutableCopy = [mArr mutableCopy];NSDictionary *dic = @{@"1":@"abc"};NSMutableDictionary *mDic = [NSMutableDictionary dictionaryWithDictionary:dic];NSDictionary *dicCopy = [dic copy];NSDictionary *dicMutableCopy = [dic mutableCopy];NSDictionary *mDicCopy = [mDic copy];NSDictionary *mDicMutableCopy = [mDic mutableCopy];NSSet *set = [NSSet setWithObject:@"1"];NSMutableSet *mSet = [NSMutableSet setWithSet:set];NSDictionary *setCopy = [set copy];NSDictionary *setMutableCopy = [set mutableCopy];NSDictionary *mSetCopy = [mDic copy];NSDictionary *mSetMutableCopy = [mDic mutableCopy]; 復制代碼

我們選取NSArray、NSMutableArray來看一下copy和mutableCopy的結果

stong與copy修飾符

strong和copy都可以用來修飾對象類型屬性,strong修飾的屬性,在將一個對象賦值給這個屬性的時候,對象不會進行內存的拷貝,直接進行地址的引用,對象的引用計數+1;copy修飾的屬性,如果該屬性是一個非集合類型,那么賦值操作的效果和strong是一樣的,如果該屬性是一個集合類型,我們在下面在詳細的解讀。

NSMutableArray屬性請使用strong修飾符

數學里面一個證明方式叫做反證法,接下來我們自定義一個類,增加一個NSMutableArray屬性,使用copy來修飾

#import <Foundation/Foundation.h> @interface TestObject : NSObject @property (nonatomic, copy) NSMutableArray *mutableArr; @end#import "TestObject.h" @implementation TestObject - (instancetype)init{self = [super init]; // self.mutableArr = [NSMutableArray arrayWithObject:@"1"];_mutableArr = [NSMutableArray arrayWithObject:@"1"];[self.mutableArr addObject:@"2"];//這一步,如果使用點語法進行屬性賦值,程序crash;如果直接使用成員變量方式賦值,代碼沒有問題return self; }//一般情況編譯器會自動給屬性添加get/set方法 - (void)setMutableArr:(NSMutableArray *)mutableArr{_mutableArr = [mutableArr copy]; } @end 復制代碼

執行下面代碼

TestObject *testObject = [TestObject new]; testObject.mutableArr = [NSMutableArray arrayWithObject:@"1"]; [testObject.mutableArr addObject:@"2"]; 復制代碼

程序crash,控制臺提示錯誤 [__NSSingleObjectArrayI addObject:]: unrecognized selector sent to instance 0x1c0017730 這一步我們就證明了如果我們使用copy來修飾一個可變的數組屬性,然后通過點語法的方式把一個可變的數組賦值給該屬性,最后該屬性指向的是一個拷貝得到的全新的不可變數組,這個時候我們可以在代碼中調用arrayWithObject等改變數組的api(因為@property (nonatomic, copy) NSMutableArray *mutableArr 告訴編譯器這是一個可變的數組),但是在運行時,這個屬性指向的是一個不可變的數組,引發unrecognized selector sent to instance 錯誤,從而導致crash。

NSArray屬性請使用copy修飾符

我們定義一個NSArray類型的屬性,目的是為了在初始化或者賦值操作后,這個數組集合就不能夠改變的(增加或者刪除元素等)。如果我們使用strong去修飾NSArray屬性,并且我們把一個可變的數組NSMutableArray對象賦值給了該屬性(父類的指針可以指向子類對象),strong并不會在內存中拷貝新的對象,只是一個地址的引用,所以NSArray類型的屬性實質上指向的是一個NSMutableArray,這個時候如果其他地方還有一個NSMutableArray指針變量指向這個NSMutableArray對象,并且通過這個變量改變了數組,也會造成NSArray類型屬性的改變,因為它們指向是一個地址內存,也就是一個對象。這就違背了我們設計的初衷,同時可能引發一些業務邏輯問題。

尾語

以上內容有任何的疑問、錯誤,請各路大神指出,同時希望能夠幫助到大家

總結

以上是生活随笔為你收集整理的Copy修饰的NSArray的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。