strong,copy,weak的區(qū)別

copy 與 strong

在日常開(kāi)發(fā)中,我們已經(jīng)習(xí)慣了一些規(guī)律,比如字符串用copy,基本數(shù)據(jù)類(lèi)型用assign,控件用strong。大多數(shù)人也知道他們的一些基本差別,但是招人時(shí)候,還是很多人答不上來(lái)。自己出去面試被提問(wèn),有時(shí)候也不知從何說(shuō)起,今天就先總結(jié)一下。


現(xiàn)在我們現(xiàn)在開(kāi)發(fā)一般都用的ARC,我們都知道,ARC是靠?jī)?nèi)存引用計(jì)數(shù)來(lái)管理內(nèi)存,每當(dāng)對(duì)象alloc,retain,strong,copy的時(shí)候,引用計(jì)數(shù)會(huì)加一,dealloc,頁(yè)面釋放時(shí)候會(huì)減一,引用計(jì)數(shù)為零的時(shí)候內(nèi)存便會(huì)釋放。

那么既然copy和strong都會(huì)讓引用計(jì)數(shù)加一,他們二者又有什么區(qū)別呢,為什么我們修飾字符串時(shí)候用copy,而在修飾控件的時(shí)候卻用strong呢?

舉個(gè)例子

現(xiàn)在有一個(gè)學(xué)校,有兩個(gè)班級(jí)。
我們先聲明兩個(gè)學(xué)生數(shù)組,一個(gè)用copy修飾,一個(gè)用strong來(lái)修飾。

@interface School : NSObject
@property (strong, nonatomic) NSArray *studentArray1;
@property (copy  , nonatomic) NSArray *studentArray2;
@end

@implementation School
//省略setter方法
@end
//School調(diào)用
main(){
  NSMutableArray *students = [@[@"小明"] mutableCopy];
  School *school = [[School alloc] init];
  school.studentArray1 = students;
  school.studentArray2 = students;
  [students addObject:@"小紅"];
  NSLog(@"studentsArray1:%@",school.studentArray1);
  NSLog(@"studentsArray2:%@",school.studentArray2);

}

可以看到,我們用同一組數(shù)據(jù)分別給兩個(gè)屬性賦值, 之后再對(duì)原數(shù)組進(jìn)行修改,那么打印結(jié)果是什么呢!

image.png

釋義

雖然我們都是聲明的不可變數(shù)組,但是我們給其賦值他的子類(lèi)mutableArray,這時(shí)候,我們修改這個(gè)可變數(shù)組。我們發(fā)現(xiàn), 用strong修飾的studentArray1中的元素個(gè)數(shù)發(fā)生了改變,而用copy進(jìn)行修飾的并沒(méi)有變化!

原因在與我們用strong進(jìn)行修飾的studentArray1與students指向同一塊內(nèi)存區(qū)域,只是將引用計(jì)數(shù)加一操作!所以當(dāng)我們修改students,studentArray1也會(huì)跟著改變!

而我們用copy修飾的studentArray2,在賦值之前,會(huì)將students里的內(nèi)容拷貝一份,創(chuàng)建一個(gè)新的內(nèi)存區(qū)域,所以?xún)烧卟皇且换厥?,students的改變不會(huì)導(dǎo)致school.studentArray2的改變!
字符串與數(shù)組同理;


深拷貝與淺拷貝

在上面這里copy將內(nèi)容拷貝了一份就是深拷貝了,淺拷貝只是將指針拷貝一份,那么copy一定是深拷貝么?并不是,這里我總結(jié)了一下

可變對(duì)象 copy 是深拷貝,會(huì)拷貝出一份新的不可變對(duì)象
不可變對(duì)象copy 是淺拷貝,只拷貝指針

關(guān)于mutableCopy

需要注意的是,copy出來(lái)會(huì)將可變對(duì)象轉(zhuǎn)為不可變對(duì)象,需要copy出可變對(duì)象要用mutableCopy!
mutableCopy都是深拷貝,并且copy出一份新的可變對(duì)象!

也就是用mutableCopy會(huì)copy出一份新的可變對(duì)象,并且原數(shù)組修改不會(huì)對(duì)新數(shù)組有影響!

那什么時(shí)候需要用weak呢?

weak 是用來(lái)修飾需要弱引用的對(duì)象
我們最常用到的就是在block、delegate或者其他一些需要解決循環(huán)引用的問(wèn)題上
但是開(kāi)頭提到了,修飾控件一般需要用到strong,但是我們發(fā)現(xiàn),當(dāng)使用XIB或者storyBoard的時(shí)候,為我們生成的屬性都是用weak修飾的這是為什么呢!

這是因?yàn)槲覀冊(cè)谑褂肵IB的時(shí)候控件已經(jīng)放在了View上,相當(dāng)于View 已經(jīng)對(duì)控件進(jìn)行了強(qiáng)引用,控件會(huì)隨View 一起釋放

我們自己手動(dòng)創(chuàng)建的控件,如果初始化后直接添加到View上,也是可以使用weak的,但是當(dāng)控件從View上remove掉的時(shí)候,就會(huì)進(jìn)行釋放!

在手動(dòng)創(chuàng)建的時(shí)候,使用 weak并沒(méi)有什么特殊的優(yōu)勢(shì),相反這塊不注意寫(xiě)法的話(huà),還容易對(duì)象會(huì)因無(wú)引用者立即被釋放,造成問(wèn)題。所以一般還是用strong來(lái)修飾

assign 一般用來(lái)修飾 integer,BOOL,枚舉,結(jié)構(gòu)體等基本數(shù)據(jù)類(lèi)型


基本就這么多吧,以上都是個(gè)人理解,大家有更深的見(jiàn)解可以提出,共同進(jìn)步!


關(guān)于深拷貝與淺拷貝還需要補(bǔ)充一點(diǎn)
自定義對(duì)象的copy都是copy的指針,比如數(shù)組中有一個(gè)自定義對(duì)象,再將數(shù)組賦值給另一個(gè)數(shù)組,那么改變其中一個(gè)數(shù)組中的對(duì)象,另一個(gè)對(duì)象也會(huì)跟著變,解決這一點(diǎn)需要在自定義對(duì)象遵循copying協(xié)議,實(shí)現(xiàn)copyWithZone方法,才能實(shí)現(xiàn)深拷貝

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀(guān)點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容