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é)果是什么呢!
釋義
雖然我們都是聲明的不可變數(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)烧卟皇且换厥鲁保瑂tudents的改變不會(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ě)法的話缓呛,還容易對(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)深拷貝