一文明白strong班缰,weak,assign, copy, retain悼枢,有源碼

我們在項(xiàng)目中經(jīng)常聲明屬性埠忘,屬性的引用類型修飾符有strong,weak,assign, copy, retain莹妒,它們分別有何含義呢名船?我們來做一次總結(jié)。

由于iOS的內(nèi)存管理機(jī)制是引用計(jì)數(shù)管理动羽,也就是說當(dāng)一個(gè)對象創(chuàng)建的時(shí)候包帚,引用計(jì)數(shù)為1,當(dāng)對這個(gè)對象進(jìn)行copy操作的時(shí)候运吓,引用計(jì)數(shù)會加1渴邦,當(dāng)不需要使用這個(gè)對象的時(shí)候,系統(tǒng)會進(jìn)行release操作拘哨,引用計(jì)數(shù)減1谋梭,當(dāng)引用計(jì)數(shù)為0的時(shí)候,系統(tǒng)就會把這個(gè)對象釋放掉倦青。

  • strong:當(dāng)使用strong修飾一個(gè)指針的時(shí)候瓮床,這個(gè)指針是一個(gè)強(qiáng)引用類型,當(dāng)它指向一個(gè)對象的時(shí)候产镐,這個(gè)對象的引用計(jì)數(shù)會加1 隘庄。
  • weak: 當(dāng)使用weak修飾一個(gè)指針的時(shí)候,這個(gè)指針是一個(gè)弱引用類型癣亚,當(dāng)它指向一個(gè)對象的時(shí)候丑掺,這個(gè)對象的引用計(jì)數(shù)并不會加1 。
  • assign: 對于值類型而言述雾,聲明的時(shí)候使用assign進(jìn)行修飾街州。
  • copy: 對于不可變類型,copy修飾的指針是淺拷貝玻孟,指向的內(nèi)存地址引用計(jì)數(shù)加1唆缴,當(dāng)copy修飾的指針值改變的時(shí)候,地址也會改變黍翎,原來指向的地址的引用計(jì)數(shù)減1.對于可變類型而言面徽,copy修飾的指針是深拷貝,把指向的對象的值拷貝一份玩敏。
  • retain: 是MRC遺留下來的修飾符斗忌,目前和strong一樣,修飾的屬性指向的地址引用計(jì)數(shù)加1 旺聚,在ARC下织阳,我們不常使用這個(gè)修飾符。

對于不喜歡看純文字的童鞋砰粹,來來來唧躲,上圖:


image.png
image.png

對于也不喜歡看圖的童鞋造挽,來來來,上代碼:

//
//  ViewController.m
//  Test
//
//  Created by wenhuanhuan on 2020/6/17.
//  Copyright ? 2020 weiman. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()

@property(nonatomic, strong)NSString * sA;
@property(nonatomic, weak)NSString * wA;
@property(nonatomic, copy)NSString * cA;
@property(nonatomic, retain)NSString * rA;

@property(nonatomic, strong)NSArray * sArr;
@property(nonatomic, weak)NSArray * wArr;
@property(nonatomic, copy)NSArray * cArr;
@property(nonatomic, retain)NSArray * rArr;

@property(nonatomic, weak)NSSet * wSet;
@property(nonatomic, assign)NSSet * aSet;

@end

@implementation ViewController

- (void)viewDidLoad {
   [super viewDidLoad];
   
   [self test_p];
   [self test_a];
}

-(void)test_a {
   @autoreleasepool {
       NSSet * set = [NSSet setWithObjects:@"1", @"2", @"3", nil];
       [self printWithObj:set mark:@"set"];//retainCount: 1
       self.wSet = set;
       [self printWithObj:set mark:@"set weak"];//retainCount: 1
       self.aSet = set;
       [self printWithObj:set mark:@"set assign"];//retainCount: 1
          
       set = [NSSet setWithObjects:@"6", @"8", @"5", nil];
       [self printWithObj:set mark:@"set change"];
   }
  
   NSLog(@"self.wSet = %p  %@", self.wSet, self.wSet);
//由于set已經(jīng)釋放了弄痹,self.aSet變成了野指針饭入,訪問野指針崩潰
  // NSLog(@"self.aSet = %p  %@", self.aSet, self.aSet);
}

-(void)test_p {
   
   NSLog(@"-------非集合,不可變類型---NSString------------\n");
   /**
   對于NSString類型,蘋果做了優(yōu)化肛真,retainCount值為-1
   */
   NSString * sA1 = @"小莉莉";
   [self printWithObj:sA1 mark:@"NSString test1"];
   NSString * sA2 = [[NSString alloc]init];
   [self printWithObj:sA2 mark:@"NSString test2"];
   printf("\n\n");
   
   //使用如下方法創(chuàng)建的NSString對象谐丢,retainCount值為1
   NSString * str = [[NSString alloc] initWithUTF8String:"小紅花"];
   [self printWithObj:str mark:@"NSString test3"];//retainCount = 1
   self.sA = str;
   [self printWithObj:str mark:@"NSString test4"];//retainCount = 2
   self.wA = str;
   [self printWithObj:str mark:@"NSString test5"];//retainCount = 2
   self.cA = str;
   [self printWithObj:str mark:@"NSString test6"];//retainCount = 3
   self.cA = @"copy";
   [self printWithObj:str mark:@"NSString test7"];//retainCount = 2
   self.rA = str;
   [self printWithObj:str mark:@"NSString test8"];//retainCount = 3
   
   
   printf("\n\n");
   NSLog(@"-------非集合澈侠,可變類型---NSMutableString------------\n");
   NSMutableString * mStr = [[NSMutableString alloc]initWithString:@"可變字符串"];
   [self printWithObj:mStr mark:@"NSMutableString test1"];//retainCount = 1
   self.sA = mStr;
   [self printWithObj:mStr mark:@"NSMutableString test2"];//retainCount = 2
   self.wA = mStr;
   [self printWithObj:mStr mark:@"NSMutableString test3"];//retainCount = 2
   self.cA = mStr;
   [self printWithObj:mStr mark:@"NSMutableString test4"];//retainCount = 2
   self.rA = mStr;
   [self printWithObj:mStr mark:@"NSMutableString test5"];//retainCount = 3
   [self printWithObj:self.sA mark:@"sA"];
   [self printWithObj:self.cA mark:@"cA"];
   
   printf("\n\n");
   NSLog(@"-------集合鹿霸,不可變類型---NSArray------------\n");
   NSArray * arr = @[@1,@2];
   [self printWithObj:arr mark:@"NSArray test1"];//retainCount = 1
   self.sArr = arr;
   [self printWithObj:arr mark:@"NSArray test2"];//retainCount = 2
   self.wArr = arr;
   [self printWithObj:arr mark:@"NSArray test3"];//retainCount = 2
   self.cArr = arr;
   [self printWithObj:arr mark:@"NSArray test4"];//retainCount = 3
   self.cArr = @[@5, @6];
   [self printWithObj:arr mark:@"NSArray test4"];//retainCount = 2
   self.rArr = arr;
   [self printWithObj:arr mark:@"NSArray test5"];//retainCount = 3
   
   printf("\n\n");
   NSLog(@"-------集合闲先,可變類型---NSMutableArray------------\n");
   NSMutableArray * mArr = [NSMutableArray arrayWithObjects:@"a",@"b", nil];
   [self printWithObj:mArr mark:@"NSMutableArray test1"];//retainCount = 1
   self.sArr = mArr;
   [self printWithObj:mArr mark:@"NSMutableArray test1"];//retainCount = 2
   self.wArr = mArr;
   [self printWithObj:mArr mark:@"NSMutableArray test1"];//retainCount = 2
   self.cArr = mArr;
   [self printWithObj:mArr mark:@"NSMutableArray test1"];//retainCount = 2
   self.cArr = @[@"iii"];
   [self printWithObj:mArr mark:@"NSMutableArray test1"];//retainCount = 2
   self.rArr = mArr;
   [self printWithObj:mArr mark:@"NSMutableArray test1"];//retainCount = 3
}

-(void)printWithObj: (id)obj mark: (NSString *)str {
   NSLog(@"%@ 值:%@采蚀, 地址: %p, retainCount: %ld", str, obj, obj, (unsigned long)[obj retainCount]);
}
@end

總結(jié)

在MRC時(shí)代,關(guān)于屬性引用計(jì)數(shù)的修飾符是retain毡熏, copy瑰谜, assign锌历,在ARC時(shí)代趟卸,引入了strong和weak蹄葱。
strong:強(qiáng)引用,引用計(jì)數(shù)增加锄列;
weak:弱引用图云,引用計(jì)數(shù)不增加;
assign:修飾值類型邻邮,修飾對象的時(shí)候琼稻,類似于weak,引用計(jì)數(shù)不增加饶囚。但是當(dāng)對象釋放的時(shí)候,assign指針不會釋放鸠补,造成野指針萝风,再次訪問,會崩潰紫岩,而weak則不會崩潰规惰。
retain:MRC下遺留的修飾符,引用計(jì)數(shù)會增加泉蝌,類似于strong歇万,ARC下,我們不常使用勋陪。
copy:對于不可變類型贪磺,copy修飾的指針是淺拷貝,指向的內(nèi)存地址引用計(jì)數(shù)加1诅愚,當(dāng)copy修飾的指針值改變的時(shí)候寒锚,地址也會改變,原來指向的地址的引用計(jì)數(shù)減1。對于可變類型而言刹前,copy修飾的指針是深拷貝泳赋,把指向的對象的值拷貝一份。

打印結(jié)果:

2020-06-21 17:19:34.926294+0800 Test[2573:170127] -------非集合喇喉,不可變類型---NSString------------

2020-06-21 17:19:34.926497+0800 Test[2573:170127] NSString test1 值:小莉莉祖今, 地址: 0x107ee01d8, retainCount: -1
2020-06-21 17:19:34.926634+0800 Test[2573:170127] NSString test2 值:, 地址: 0x7fff80971d08, retainCount: -1


2020-06-21 17:19:34.926823+0800 Test[2573:170127] NSString test3 值:小紅花拣技, 地址: 0x60000332af20, retainCount: 1
2020-06-21 17:19:34.926944+0800 Test[2573:170127] NSString test4 值:小紅花千诬, 地址: 0x60000332af20, retainCount: 2
2020-06-21 17:19:34.927091+0800 Test[2573:170127] NSString test5 值:小紅花, 地址: 0x60000332af20, retainCount: 2
2020-06-21 17:19:34.927214+0800 Test[2573:170127] NSString test6 值:小紅花过咬, 地址: 0x60000332af20, retainCount: 3
2020-06-21 17:19:34.927340+0800 Test[2573:170127] NSString test7 值:小紅花大渤, 地址: 0x60000332af20, retainCount: 2
2020-06-21 17:19:34.927552+0800 Test[2573:170127] NSString test8 值:小紅花, 地址: 0x60000332af20, retainCount: 3


2020-06-21 17:19:34.927868+0800 Test[2573:170127] -------非集合掸绞,可變類型---NSMutableString------------

2020-06-21 17:19:34.928174+0800 Test[2573:170127] NSMutableString test1 值:可變字符串泵三, 地址: 0x600003d37420, retainCount: 1
2020-06-21 17:19:34.928456+0800 Test[2573:170127] NSMutableString test2 值:可變字符串, 地址: 0x600003d37420, retainCount: 2
2020-06-21 17:19:34.928759+0800 Test[2573:170127] NSMutableString test3 值:可變字符串衔掸, 地址: 0x600003d37420, retainCount: 2
2020-06-21 17:19:34.929087+0800 Test[2573:170127] NSMutableString test4 值:可變字符串烫幕, 地址: 0x600003d37420, retainCount: 2
2020-06-21 17:19:34.935395+0800 Test[2573:170127] NSMutableString test5 值:可變字符串, 地址: 0x600003d37420, retainCount: 3
2020-06-21 17:19:34.935553+0800 Test[2573:170127] sA 值:可變字符串敞映, 地址: 0x600003d37420, retainCount: 3
2020-06-21 17:19:34.935701+0800 Test[2573:170127] cA 值:可變字符串较曼, 地址: 0x600003d33c60, retainCount: 1


2020-06-21 17:19:34.935822+0800 Test[2573:170127] -------集合,不可變類型---NSArray------------

2020-06-21 17:19:34.936007+0800 Test[2573:170127] NSArray test1 值:(
    1,
    2
)振愿, 地址: 0x6000033258e0, retainCount: 1
2020-06-21 17:19:34.936148+0800 Test[2573:170127] NSArray test2 值:(
    1,
    2
)捷犹, 地址: 0x6000033258e0, retainCount: 2
2020-06-21 17:19:34.936287+0800 Test[2573:170127] NSArray test3 值:(
    1,
    2
), 地址: 0x6000033258e0, retainCount: 2
2020-06-21 17:19:34.936424+0800 Test[2573:170127] NSArray test4 值:(
    1,
    2
)冕末, 地址: 0x6000033258e0, retainCount: 3
2020-06-21 17:19:34.936564+0800 Test[2573:170127] NSArray test4 值:(
    1,
    2
)萍歉, 地址: 0x6000033258e0, retainCount: 2
2020-06-21 17:19:34.936717+0800 Test[2573:170127] NSArray test5 值:(
    1,
    2
), 地址: 0x6000033258e0, retainCount: 3


2020-06-21 17:19:34.936843+0800 Test[2573:170127] -------集合档桃,可變類型---NSMutableArray------------

2020-06-21 17:19:34.936990+0800 Test[2573:170127] NSMutableArray test1 值:(
    a,
    b
)枪孩, 地址: 0x600003d37690, retainCount: 1
2020-06-21 17:19:34.937306+0800 Test[2573:170127] NSMutableArray test1 值:(
    a,
    b
), 地址: 0x600003d37690, retainCount: 2
2020-06-21 17:19:34.937627+0800 Test[2573:170127] NSMutableArray test1 值:(
    a,
    b
)藻肄, 地址: 0x600003d37690, retainCount: 2
2020-06-21 17:19:34.937942+0800 Test[2573:170127] NSMutableArray test1 值:(
    a,
    b
)蔑舞, 地址: 0x600003d37690, retainCount: 2
2020-06-21 17:19:34.938245+0800 Test[2573:170127] NSMutableArray test1 值:(
    a,
    b
), 地址: 0x600003d37690, retainCount: 2
2020-06-21 17:19:34.938527+0800 Test[2573:170127] NSMutableArray test1 值:(
    a,
    b
)嘹屯, 地址: 0x600003d37690, retainCount: 3
2020-06-21 17:19:34.938856+0800 Test[2573:170127] set 值:{(
    1,
    2,
    3
)}攻询, 地址: 0x600003d38840, retainCount: 1
2020-06-21 17:19:34.939117+0800 Test[2573:170127] set weak 值:{(
    1,
    2,
    3
)}, 地址: 0x600003d38840, retainCount: 1
2020-06-21 17:19:34.939376+0800 Test[2573:170127] set assign 值:{(
    1,
    2,
    3
)}抚垄, 地址: 0x600003d38840, retainCount: 1
2020-06-21 17:19:34.939715+0800 Test[2573:170127] set change 值:{(
    6,
    8,
    5
)}蜕窿, 地址: 0x600003d376f0, retainCount: 1
2020-06-21 17:19:34.939985+0800 Test[2573:170127] self.wSet = 0x0  (null)
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末谋逻,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子桐经,更是在濱河造成了極大的恐慌毁兆,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,755評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件阴挣,死亡現(xiàn)場離奇詭異气堕,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)畔咧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評論 3 395
  • 文/潘曉璐 我一進(jìn)店門茎芭,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人誓沸,你說我怎么就攤上這事梅桩。” “怎么了拜隧?”我有些...
    開封第一講書人閱讀 165,138評論 0 355
  • 文/不壞的土叔 我叫張陵宿百,是天一觀的道長。 經(jīng)常有香客問我洪添,道長垦页,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,791評論 1 295
  • 正文 為了忘掉前任干奢,我火速辦了婚禮痊焊,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘忿峻。我一直安慰自己薄啥,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評論 6 392
  • 文/花漫 我一把揭開白布逛尚。 她就那樣靜靜地躺著罪佳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪黑低。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,631評論 1 305
  • 那天酌毡,我揣著相機(jī)與錄音克握,去河邊找鬼。 笑死枷踏,一個(gè)胖子當(dāng)著我的面吹牛菩暗,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播旭蠕,決...
    沈念sama閱讀 40,362評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼停团,長吁一口氣:“原來是場噩夢啊……” “哼旷坦!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起佑稠,我...
    開封第一講書人閱讀 39,264評論 0 276
  • 序言:老撾萬榮一對情侶失蹤秒梅,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后舌胶,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體捆蜀,經(jīng)...
    沈念sama閱讀 45,724評論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評論 3 336
  • 正文 我和宋清朗相戀三年幔嫂,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了辆它。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,040評論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡履恩,死狀恐怖锰茉,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情切心,我是刑警寧澤飒筑,帶...
    沈念sama閱讀 35,742評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站昙衅,受9級特大地震影響扬霜,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜而涉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評論 3 330
  • 文/蒙蒙 一著瓶、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧啼县,春花似錦材原、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至子刮,卻和暖如春威酒,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背挺峡。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評論 1 270
  • 我被黑心中介騙來泰國打工葵孤, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人橱赠。 一個(gè)月前我還...
    沈念sama閱讀 48,247評論 3 371
  • 正文 我出身青樓尤仍,卻偏偏與公主長得像,于是被迫代替她去往敵國和親狭姨。 傳聞我的和親對象是個(gè)殘疾皇子宰啦,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評論 2 355