在ARC中的assign和weak可以說非常相像,導致有很多人誤以為他們是一摸一樣的,在任何時候都可以划等價,但事實卻不是這樣。
在群里,有人問,id類型的delegate屬性到底是用assign還是weak
@property (weak, nonatomic) id<AnyDelegate> delegate; @property (assign, nonatomic) id<AnyDelegate> delegate;
大家眾說紛紜,說都可以的,說assign的,說weak的都有,下面我們來看一本書中的描述:
“The main difference between weak and assign is that the with weak, once the object being pointed to is no longer valid, the pointer is nilled out. Assigning the pointer the value nil avoids many crashes as messages sent to nil are essentially no-ops”
Excerpt From: Daniel H Steinberg.
“Developing iOS 7 Apps for iPad and iPhone.” Dim Sum Thinking, Inc, 2014. iBooks. iTunes - Books
大致的意思是說,weak比assign多了一個功能就是當屬性所指向的對象消失的時候(也就是內存引用計數為0)會自動賦值為nil,這樣再向weak修飾的屬性發送消息就不會導致野指針操作crash。
可能不太好理解下面我寫了一個演示程序。
OC:
// // ViewController.m // weak與assgin的區別 // // Created by bihongbo on 15/3/19. // Copyright (c) 2015年 畢洪博. All rights reserved. // #import "ViewController.h" @interface ViewController () @property (nonatomic,weak) id weakPoint; @property (nonatomic,assign) id assignPoint; @property (nonatomic,strong) id strongPoint; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; self.strongPoint = [NSDate date]; NSLog(@"strong屬性:%@",self.strongPoint); self.weakPoint = self.strongPoint; self.assignPoint = self.strongPoint; self.strongPoint = nil; NSLog(@"weak屬性:%@",self.weakPoint); // NSLog(@"assign屬性:%@",self.assignPoint); } @end
當程序中的注釋被打開時,運行程序有可能會崩潰(有時候不崩潰,你可能需要多運行幾次),這是因為當assign指針所指向的內存被釋放(釋放並不等於抹除,只是引用計數為0),不會自動賦值nil,這樣再引用self.assignPoint就會導致野指針操作,如果這個操作發生時內存還沒有改變內容,依舊可以輸出正確的結果,而如果發生時內存內容被改變了,就會crash。
結論:在ARC模式下編程時,指針變量一定要用weak修飾,只有基本數據類型和結構體需要用assgin,例如delegate,一定要用weak修飾。
goodluck!
