修飾符weak引發(fā)的思考

背景

??????在測試中發(fā)現(xiàn)有個(gè)網(wǎng)頁沒有加載出來,查找原因時(shí),發(fā)現(xiàn)是由于用了weak修飾了一個(gè)NSURL的全局變量哮内,出了方法作用域之后祈噪,這個(gè)NSURL的全局變量的值就變?yōu)?code>nil了泽铛,因此網(wǎng)頁才沒能加載成功。

思考和實(shí)踐

??????對于weak這個(gè)修飾符辑鲤,之前并沒有做的太多的學(xué)習(xí)和研究盔腔,只是知道在修飾UI控件以及代理的時(shí)候使用。
??????做了一個(gè)簡單的測試月褥,分別用weak修飾NSArray弛随、NSMutableArrayNSDictionary宁赤、NSMutableDictionary舀透、NSURL,其中數(shù)組和URL在另一個(gè)方法中調(diào)用是都為nil了决左,但字典仍可以正常的存取值愕够。至于為什么會(huì)出現(xiàn)這種結(jié)果,不得而知佛猛,如果有哪位小伙伴知道原理還請?jiān)谠u(píng)論區(qū)留言惑芭。對于OC中的對象建議還是使用strong或者copy進(jìn)行修飾,以免因?yàn)樽兞繛?code>nil而引起不必要的問題继找。

變量聲明

@property(nonatomic,weak)NSArray * weakArray;
@property(nonatomic,weak)NSMutableArray * weakMutableArray;
@property(nonatomic,weak)NSDictionary * weakDictionary;
@property(nonatomic,weak)NSMutableDictionary * weakMutableDictionary;
@property(nonatomic,weak)NSURL * weakUrl;

運(yùn)行結(jié)果

NSArray * weakArray = [NSArray arrayWithObject:@"weakArray"];
self.weakArray = weakArray;

NSLog(@"viewDidLoad方法中 weakArray = %@ %p",self.weakArray,self.weakArray);// viewDidLoad方法中 weakArray = (weakArray) 0x600003534a10

NSMutableArray * weakMutableArray = [NSMutableArray arrayWithObject:@"weakMutableArray"];
self.weakMutableArray = weakMutableArray;

NSLog(@"viewDidLoad方法中 weakMutableArray = %@ %p",self.weakMutableArray,self.weakMutableArray);//viewDidLoad方法中 weakMutableArray = (weakMutableArray) 0x60000396e130

NSLog(@"字典");

NSDictionary * weakDictionary = [NSDictionary dictionaryWithObjectsAndKeys:@"weakDictionary",@"weak",nil];
self.weakDictionary = weakDictionary;

NSLog(@"viewDidLoad方法中 weakDictionary = %@ %p",self.weakDictionary,self.weakDictionary);//viewDidLoad方法中 weakDictionary = {weak = weakDictionary;} 0x6000022611c0

NSMutableDictionary * weakMutableDictionary = [NSMutableDictionary dictionaryWithObjectsAndKeys:@"weakMutableDictionary",@"weak",nil];
self.weakMutableDictionary = weakMutableDictionary;

NSLog(@"viewDidLoad方法中 weakMutableDictionary = %@ %p",self.weakMutableDictionary,self.weakMutableDictionary);// viewDidLoad方法中 weakMutableDictionary = {weak = weakMutableDictionary;} 0x6000037701a0

NSURL * weakUrl = [NSURL URLWithString:@"weakUrl"];
self.weakUrl = weakUrl;

NSLog(@"viewDidLoad方法中 weakUrl = %@ %p",self.weakUrl,self.weakUrl);// viewDidLoad方法中 weakUrl = weakUrl 0x600001419a40



-(void)viewWillAppear:(BOOL)animated{
    [super viewWillAppear:animated];
    NSLog(@"viewWillAppear方法中 weakArray = %@ %p",self.weakArray,self.weakArray);// viewWillAppear方法中 weakArray = (null) 0x0
    NSLog(@"viewWillAppear方法中 weakMutableArray = %@ %p",self.weakMutableArray,self.weakMutableArray);// viewWillAppear方法中 weakMutableArray = (null) 0x0
    NSLog(@"viewWillAppear方法中 weakDictionary = %@ %p",self.weakDictionary,self.weakDictionary);//viewWillAppear方法中 weakDictionary = {weak = weakDictionary;} 0x6000022611c0
    NSLog(@"viewWillAppear方法中 weakMutableDictionary = %@ %p",self.weakMutableDictionary,self.weakMutableDictionary);// viewWillAppear方法中 weakMutableDictionary = {weak = weakMutableDictionary;} 0x6000037701a0
    NSLog(@"viewWillAppear方法中 weakUrl = %@ %p",self.weakUrl,self.weakUrl);// viewWillAppear方法中 weakUrl = (null) 0x0
}
viewdidload運(yùn)行結(jié)果
viewwillappear運(yùn)行結(jié)果
copy和strong修飾數(shù)組
  1. 當(dāng)源對象為不可變數(shù)組時(shí)强衡,不管是可變還是不可變數(shù)組,使用copystrong進(jìn)行修飾時(shí),最終數(shù)組都會(huì)變?yōu)椴豢勺償?shù)組漩勤,內(nèi)存地址不變感挥。
  2. 當(dāng)源對象為可變數(shù)組時(shí)
  • 使用copy修飾可變數(shù)組或者不可變數(shù)組時(shí),即使聲明的是可變數(shù)組越败,最終變?yōu)橐粋€(gè)新的不可變數(shù)組触幼,如果這時(shí)調(diào)用可變數(shù)組的方法,像addObject究飞、removeObject等方法時(shí)置谦,會(huì)導(dǎo)致程序崩潰,因?yàn)椴豢勺償?shù)組沒有這些方法亿傅。
  • 使用strong修飾不可變數(shù)組時(shí)媒峡,最終數(shù)組都會(huì)變?yōu)椴豢勺償?shù)組,內(nèi)存地址不變葵擎。這時(shí)候仍然可以調(diào)用可變數(shù)組的方法谅阿,不過不能直接調(diào)用,需要強(qiáng)轉(zhuǎn)或者使用performSelector:withObject:這種方式酬滤。
  • 使用strong修飾可變數(shù)組時(shí)签餐,數(shù)組依然是可變數(shù)組,內(nèi)存地址不變盯串。
@property(nonatomic,copy)NSArray * coArray;
@property(nonatomic,copy)NSMutableArray * coMutableArray;
@property(nonatomic,strong)NSArray * strongArray;
@property(nonatomic,strong)NSMutableArray * strongMutableArray;

NSArray * array = [NSArray arrayWithObject:@"array"];
NSLog(@"%@  %p",[array class],array); // __NSSingleObjectArrayI 0x6000015937a0

self.coArray = array;
self.coMutableArray = array;
self.strongArray = array;
self.strongMutableArray = array;

NSLog(@"%@  %p",[self.coArray class],self.coArray); // __NSSingleObjectArrayI 0x6000015937a0
NSLog(@"%@  %p",[self.coMutableArray class],self.coMutableArray);// __NSSingleObjectArrayI 0x6000015937a0
NSLog(@"%@  %p",[self.strongArray class],self.strongArray);// __NSSingleObjectArrayI 0x6000015937a0
NSLog(@"%@  %p",[self.strongMutableArray class],self.strongMutableArray);// __NSSingleObjectArrayI 0x6000015937a0

NSMutableArray * mutableArray = [NSMutableArray arrayWithObject:@"mutableArray"];
NSLog(@"%@  %p",[mutableArray class],mutableArray);// __NSArrayM 0x6000019dd8c0

self.coArray = mutableArray;
self.coMutableArray = mutableArray;
self.strongArray = mutableArray;
self.strongMutableArray = mutableArray;

NSLog(@"%@  %p",[self.coArray class],self.coArray);// __NSSingleObjectArrayI 0x6000015935c0
NSLog(@"%@  %p",[self.coMutableArray class],self.coMutableArray);// __NSSingleObjectArrayI 0x600001593590

[self.coMutableArray addObject:@"coMutableArray"];// -[__NSSingleObjectArrayI addObject:]: unrecognized selector sent to instance

NSLog(@"%@  %p",[self.strongArray class],self.strongArray);// __NSArrayM 0x6000019dd8c0
NSLog(@"%@  %p",[self.strongMutableArray class],self.strongMutableArray);// __NSArrayM 0x6000019dd8c0
數(shù)組執(zhí)行結(jié)果
對象的copy與mutableCopy
  1. 當(dāng)源對象為不可變時(shí),使用copy時(shí)不會(huì)生成新的對象氯檐,即指針拷貝(淺拷貝);使用mutableCopy會(huì)生成一個(gè)新的可變對象体捏,即對象拷貝(深拷貝)冠摄。
  2. 當(dāng)源對象為可變時(shí),使用copymutableCopy時(shí)都會(huì)生成一個(gè)新的對象几缭,即對象拷貝(深拷貝)河泳,區(qū)別在于:使用copy生成的對象為不可變的,而mutableCopy生成的對象是可變的奏司。

測試代碼如下:

NSString * string = @"string";

NSLog(@"string = %@  %p",[string class],string);
// __NSCFConstantString  0x10eff20a0

NSLog(@"copyString = %@  %p",[[string copy] class],[string copy]);
// __NSCFConstantString  0x10eff20a0

NSLog(@"mutableCopyString = %@  %p",[[string mutableCopy] class],[string mutableCopy]);
// __NSCFString  0x600003f8e250

NSLog(@"NSMutableString\n");

NSMutableString * mutableString = [NSMutableString stringWithString:@"mutableString"];

NSLog(@"mutableString = %@  %p",[mutableString class],mutableString);
// __NSCFString  0x600003dfa670


NSLog(@"copy_mutableString = %@  %p",[[mutableString copy] class],[mutableString copy]);
// __NSCFString  0x6000033fc340
/**
    這個(gè)地方不知道為什么打印的結(jié)果是可變字符串 乔询,做了一個(gè)測試樟插,調(diào)用可變字符串的appendString方法韵洋,崩潰了
    NSMutableString * copy_mutableString = [mutableString copy];
    [copy_mutableString appendString:@"append"];
    NSLog(@"%@",copy_mutableString); // Attempt to mutate immutable object with appendString:
 */

NSLog(@"mutableCopy_mutableString = %@  %p",[[mutableString mutableCopy] class],[mutableString mutableCopy]);
// __NSCFString  0x600003dfa940

NSLog(@"NSArray\n");

NSArray * array = [NSArray arrayWithObject:@"array"];

NSLog(@"array = %@  %p",[array class],array);
// __NSSingleObjectArrayI  0x6000031a9960

NSLog(@"copy_array = %@  %p",[[array copy] class],[array copy]);
// __NSSingleObjectArrayI  0x6000031a9960

NSLog(@"mutableCopy_array = %@  %p",[[array mutableCopy] class],[array mutableCopy]);
// __NSArrayM  0x600003dfa310

NSLog(@"NSMutableArray\n");

NSMutableArray * mutablearray = [NSMutableArray arrayWithObject:@"mutablearray"];

NSLog(@"mutablearray = %@  %p",[mutablearray class],mutablearray);
// __NSArrayM  0x600003dfdb00

NSLog(@"copy_mutablearray = %@  %p",[[mutablearray copy] class],[mutablearray copy]);
// __NSSingleObjectArrayI  0x6000031bd0a0

NSLog(@"mutableCopy_mutablearray = %@  %p",[[mutablearray mutableCopy] class],[mutablearray mutableCopy]);
// __NSArrayM  0x600003dfd710
字符串

數(shù)組
注:本文中的測試SDK版本為12.2,Xcode 10.2 黄锤,如有錯(cuò)誤歡迎留言指正搪缨。
參考文章

iOS內(nèi)存管理(6)--NSArray與NSMutableArray用copy修飾還是strong
assign weak retain strong copy關(guān)鍵字的區(qū)別
整理一下OC中的那些屬性修飾符

iOS Copy與MutableCopy 和 Copy與Strong 深度解析
iOS中copy和mutableCopy詳解
聊聊NSString為什么用copy

iOS學(xué)習(xí)——屬性引用self.xx與_xx的區(qū)別
iOS 同時(shí)重寫setter和getter時(shí)候報(bào)錯(cuò):Use of undeclared identifier '_name';did you mean 'name'
ios中set和get方法

iOS 底層解析weak的實(shí)現(xiàn)原理(包含weak對象的初始化,引用鸵熟,釋放的分析)

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末副编,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子流强,更是在濱河造成了極大的恐慌痹届,老刑警劉巖呻待,帶你破解...
    沈念sama閱讀 218,755評(píng)論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異队腐,居然都是意外死亡蚕捉,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,305評(píng)論 3 395
  • 文/潘曉璐 我一進(jìn)店門柴淘,熙熙樓的掌柜王于貴愁眉苦臉地迎上來迫淹,“玉大人,你說我怎么就攤上這事为严×舶荆” “怎么了?”我有些...
    開封第一講書人閱讀 165,138評(píng)論 0 355
  • 文/不壞的土叔 我叫張陵第股,是天一觀的道長应民。 經(jīng)常有香客問我,道長炸茧,這世上最難降的妖魔是什么瑞妇? 我笑而不...
    開封第一講書人閱讀 58,791評(píng)論 1 295
  • 正文 為了忘掉前任,我火速辦了婚禮梭冠,結(jié)果婚禮上辕狰,老公的妹妹穿的比我還像新娘。我一直安慰自己控漠,他們只是感情好蔓倍,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,794評(píng)論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盐捷,像睡著了一般偶翅。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上碉渡,一...
    開封第一講書人閱讀 51,631評(píng)論 1 305
  • 那天聚谁,我揣著相機(jī)與錄音,去河邊找鬼滞诺。 笑死形导,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的习霹。 我是一名探鬼主播朵耕,決...
    沈念sama閱讀 40,362評(píng)論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼淋叶!你這毒婦竟也來了阎曹?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,264評(píng)論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎处嫌,沒想到半個(gè)月后栅贴,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,724評(píng)論 1 315
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡熏迹,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,900評(píng)論 3 336
  • 正文 我和宋清朗相戀三年筹误,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片癣缅。...
    茶點(diǎn)故事閱讀 40,040評(píng)論 1 350
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡厨剪,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出友存,到底是詐尸還是另有隱情祷膳,我是刑警寧澤,帶...
    沈念sama閱讀 35,742評(píng)論 5 346
  • 正文 年R本政府宣布屡立,位于F島的核電站直晨,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏膨俐。R本人自食惡果不足惜勇皇,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,364評(píng)論 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望焚刺。 院中可真熱鬧敛摘,春花似錦、人聲如沸乳愉。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,944評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蔓姚。三九已至捕虽,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間坡脐,已是汗流浹背泄私。 一陣腳步聲響...
    開封第一講書人閱讀 33,060評(píng)論 1 270
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留备闲,地道東北人晌端。 一個(gè)月前我還...
    沈念sama閱讀 48,247評(píng)論 3 371
  • 正文 我出身青樓,卻偏偏與公主長得像浅役,于是被迫代替她去往敵國和親斩松。 傳聞我的和親對象是個(gè)殘疾皇子伶唯,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,979評(píng)論 2 355