OC對象:不可變對象copy是淺拷貝肌括,其他(可變對象的mutablecopy與copy付材,不可變對象的mutablecopy)是都深拷貝刨肃;copy是不可變對象,mutablecopy是可變對象盅弛;
copy修飾字符串:在setter方法中會判斷傳入的字符串是否是可變的钱骂,如果是可變的就分配新的內(nèi)存再賦值;如果是不可變的就直接賦值地址挪鹏,而實際上開發(fā)中其實大量使用的是不可變的字符串见秽,所有最好使用strong修飾字符串(針對傳入不可變的字符串),可以提升性能(在setter方法中會減少一次判斷)讨盒;
注意:針對于當把NSMutableString賦值給NSString的時候解取,才會有不同,如果是賦值是NSString對象返顺,那么使用copy還是strong禀苦,結(jié)果都是一樣的,因為NSString對象根本就不能改變自身的值遂鹊,他是不可變的振乏。
把一個對象賦值給一個屬性變量,當這個對象變化了秉扑,如果希望屬性變量變化就使用strong屬性昆码,如果希望屬性變量不跟著變化,就是用copy屬性邻储。
由此可以看出:?
對源頭是NSMutableString的字符串赋咽,strong僅僅是指針引用,增加了引用計數(shù)器吨娜,這樣源頭改變的時候脓匿,用這種strong方式聲明的變量(無論被賦值的變量是可變的還是不可變的),它也會跟著改變;而copy聲明的變量宦赠,它不會跟著源頭改變陪毡,它實際上是深拷貝米母。
對源頭是NSString的字符串,無論是strong聲明的變量還是copy聲明的變量毡琉,當?shù)诙卧搭^的字符串重新指向其它的地方的時候(指針地址不變铁瞒,指向的內(nèi)存地址變了),屬性變量指針地址不變桅滋,指向的內(nèi)存地址還是指向原來的最初的那個位置慧耍,也就是說其實二者都是指針引用,也就是淺拷貝丐谋。
另外說明一下芍碧,這兩者對內(nèi)存計數(shù)的影響都是一樣的,都會增加內(nèi)存引用計數(shù)号俐,都需要在最后的時候做處理泌豆。
其實說白了,對字符串為啥要用這兩種方式吏饿?我覺得還是一個安全問題踪危,比如聲明的一個NSString *mStr變量,然后把一個NSMutableString *str變量的賦值給它了猪落,如果要求mStr跟著str變化陨倡,那么就用strong;如果mStr不能跟著str一起變化,那就用copy许布。而對于要把NSString類型的字符串賦值給mStr兴革,那兩都沒啥區(qū)別。不會影響安全性蜜唾,內(nèi)存管理也一樣杂曲。
用copy修飾Block時,在MRC和ARC下的區(qū)別:
MRC:block訪問外部局部變量袁余,block存放棧里面擎勘,只要block訪問變量,而且是整個APP都存在的變量颖榜,那么肯定在全局區(qū)棚饵,在MRC中,不能使用retain引用block掩完,因為不會放在堆里面噪漾,在ARC中智能使用copy才會把block放在堆里面
ARC:只要block訪問外部局部變量,block就會放在堆里面且蓬,可以使用strong去引用欣硼,因為本身就已經(jīng)存放在堆區(qū)了,也可以使用copy恶阴,但是strong性能更好诈胜;
深拷貝豹障,淺拷貝與指針引用:
深拷貝:生成新的指針(指針地址不同)指向一塊新的內(nèi)存保存值;
淺拷貝:內(nèi)存地址不變焦匈,生成一個新的指針地址指向相同的內(nèi)存地址血公;
指針引用:共用同一個指針,指向相同的內(nèi)存地址缓熟,只是指針的引用計數(shù)+1累魔;