iOS中assign與weak园担,retain與strong的區(qū)別以及block的屬性修飾符探討

以前在沒有ARC(automatic reference counting)的時候我們使用assign與retain來修飾屬性娱挨,后來引入了更安全的weak和strong來修飾屬性

一抖苦、探討assign毯侦、retain洒缀、strong瑰谜、weak的區(qū)別

assign與weak

兩者都是弱引用,assign通常用于普通類型屬性(如int,NSInteger)树绩,常見的還會用于delegate對象的屬性修飾萨脑,基本上來說兩者是可以通用的。

Q:那對于delegate的屬性修飾符到底是用assign好饺饭,還是weak好呢砚哗?

分析:weak在引用的對象被釋放的時候會將delegate置為nil,而assign修飾的delegate依然會指向原來的位置砰奕,這樣在delegate引用的對象被釋放后蛛芥,delegate就會變成野指針提鸟。在OC中你給你一個nil對象發(fā)送消息不會crash,但是給一個對象(如:野指針)發(fā)送他不能響應(yīng)的消息是會crash的仅淑,所以總的來說weak要比assign安全一些称勋。

A:像delegate屬性的修飾符建議用weak修飾而不是assign,這樣你使用delegate的時候就不需要判斷delegate對象是不是存在了涯竟。

retain和strong

他倆都是強引用赡鲜,除了某些情況下不一樣,比如修飾block庐船,其他的時候也是可以通用的银酬。

關(guān)于修飾block的時候,retain和strong有什么區(qū)別請看下面??

二筐钟、探討block的屬性修飾符

提示一下揩瞪,現(xiàn)在的Xcode創(chuàng)建的新項目都是默認(rèn)采用ARC,我們?nèi)绻胍獙こ踢M行手動內(nèi)存管理該怎么辦篓冲?我們可以在TARGET -> Build Settings 下搜索Garbage Collection李破,會搜出Objective-C Automatic Reference Counting,將其設(shè)置為NO即可使整個工程處于MRC環(huán)境下了壹将。那如果只想對某個類文件采用MRC嗤攻,工程的其他類都用ARC呢,那我們可以在TARGET -> Build Phase -> Compile Sources下找到對應(yīng)的類诽俯,雙擊修改Compiler flag妇菱,然后添加-fno-objc-arc即可,反之在MRC工程下的某個類中添加-fobjc-arc即可使用ARC暴区。

MRC下

(1)用retain修飾block 且 不訪問 external變量情況下

@interface ViewController ()
@property (nonatomic, retain) TestBlock block;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    __block NSInteger num = 1;
    self.block = ^{
        //num = 2;
    };
    NSLog(@"---%@",self.block);
}
@end

打印結(jié)果:

---<__NSGlobalBlock__: 0x1008b9088>

(2)用retain修飾block 且 訪問 external變量情況下

@interface ViewController ()
@property (nonatomic, retain) TestBlock block;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    __block NSInteger num = 1;
    self.block = ^{
        num = 2;
    };
    NSLog(@"---%@",self.block);
}

@end

打印結(jié)果:

---<__NSStackBlock__: 0x7ffeeb094988>

(3)用strong或copy修飾block 且 不訪問 external變量情況下

@interface ViewController ()
@property (nonatomic, strong) TestBlock block;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    __block NSInteger num = 1;
    self.block = ^{
        //num = 2;
    };
    NSLog(@"---%@",self.block);
}

@end

打印結(jié)果:

---<__NSGlobalBlock__: 0x10781c098>

(4)用strong或copy修飾block 且 訪問 external變量情況下

@interface ViewController ()
@property (nonatomic, strong) TestBlock block;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    __block NSInteger num = 1;
    self.block = ^{
        num = 2;
    };
    NSLog(@"---%@",self.block);
}
@end

打印結(jié)果:

---<__NSMallocBlock__: 0x600002e4e5e0>

ARC下

(1)用retain修飾block 且 不訪問 external變量情況下

@interface ViewController ()
@property (nonatomic, retain) TestBlock block;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    __block NSInteger num = 1;
    self.block = ^{
        //num = 2;
    };
    NSLog(@"---%@",self.block);
}
@end

打印結(jié)果:

---<__NSGlobalBlock__: 0x10f4b30a0>

(2)用retain修飾block 且 訪問 external變量情況下

@interface ViewController ()
@property (nonatomic, retain) TestBlock block;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    __block NSInteger num = 1;
    self.block = ^{
        num = 2;
    };
    NSLog(@"---%@",self.block);
}

@end

打印結(jié)果:

---<__NSMallocBlock__: 0x600002c78120>

(3)用strong或copy修飾block 且 不訪問 external變量情況下

@interface ViewController ()
@property (nonatomic, strong) TestBlock block;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    __block NSInteger num = 1;
    self.block = ^{
        //num = 2;
    };
    NSLog(@"---%@",self.block);
}

@end

打印結(jié)果:

---<__NSGlobalBlock__: 0x10ff380a8>

(4)用strong或copy修飾block 且 訪問 external變量情況下

@interface ViewController ()
@property (nonatomic, strong) TestBlock block;
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    __block NSInteger num = 1;
    self.block = ^{
        num = 2;
    };
    NSLog(@"---%@",self.block);
}
@end

打印結(jié)果:

---<__NSMallocBlock__: 0x60000075a550>

結(jié)果對照表(訪問:指的是訪問external變量恶耽,反之亦然):

retain 不訪問 strong(copy)不訪問 retain 訪問 strong(copy)訪問
MRC NSGlobalBlock NSGlobalBlock NSStackBlock NSMallocBlock
ARC NSGlobalBlock NSGlobalBlock NSMallocBlock NSMallocBlock

結(jié)論

  • 只要不引入external變量,無論是MRC還是ARC颜启,無論是retain還是strong修飾block偷俭,block屬性都是存在全局?jǐn)?shù)據(jù)區(qū)
  • 引入external變量時,retain和strong(copy)是有區(qū)別的缰盏,
    MRC時涌萤,block存在棧區(qū)(stack)的,因此使用的時候要注意此時的block是否還存在口猜,以免操作了野指針而閃退负溪。
    ARC時,block是存在堆區(qū)(heap)的济炎。

總結(jié)

  • 所以說block的屬性修飾符應(yīng)該用strongcopy比較安全些川抡。
  • 對block來說,屬性修飾符用strongcopy效果是一樣的。

【注意】上述提到的external變量不是指C語言上的那個external變量崖堤,本處指的是block外面變量侍咱,可以是局部變量,也是是一個屬性密幔。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末楔脯,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子胯甩,更是在濱河造成了極大的恐慌昧廷,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,084評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件偎箫,死亡現(xiàn)場離奇詭異木柬,居然都是意外死亡,警方通過查閱死者的電腦和手機淹办,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,623評論 3 392
  • 文/潘曉璐 我一進店門眉枕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人娇唯,你說我怎么就攤上這事〖帕幔” “怎么了塔插?”我有些...
    開封第一講書人閱讀 163,450評論 0 353
  • 文/不壞的土叔 我叫張陵,是天一觀的道長拓哟。 經(jīng)常有香客問我想许,道長,這世上最難降的妖魔是什么断序? 我笑而不...
    開封第一講書人閱讀 58,322評論 1 293
  • 正文 為了忘掉前任流纹,我火速辦了婚禮,結(jié)果婚禮上违诗,老公的妹妹穿的比我還像新娘漱凝。我一直安慰自己,他們只是感情好诸迟,可當(dāng)我...
    茶點故事閱讀 67,370評論 6 390
  • 文/花漫 我一把揭開白布茸炒。 她就那樣靜靜地躺著,像睡著了一般阵苇。 火紅的嫁衣襯著肌膚如雪壁公。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,274評論 1 300
  • 那天绅项,我揣著相機與錄音紊册,去河邊找鬼。 笑死快耿,一個胖子當(dāng)著我的面吹牛囊陡,可吹牛的內(nèi)容都是我干的芳绩。 我是一名探鬼主播,決...
    沈念sama閱讀 40,126評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼关斜,長吁一口氣:“原來是場噩夢啊……” “哼示括!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起痢畜,我...
    開封第一講書人閱讀 38,980評論 0 275
  • 序言:老撾萬榮一對情侶失蹤垛膝,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后丁稀,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體吼拥,經(jīng)...
    沈念sama閱讀 45,414評論 1 313
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,599評論 3 334
  • 正文 我和宋清朗相戀三年线衫,在試婚紗的時候發(fā)現(xiàn)自己被綠了凿可。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,773評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡授账,死狀恐怖枯跑,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情白热,我是刑警寧澤敛助,帶...
    沈念sama閱讀 35,470評論 5 344
  • 正文 年R本政府宣布,位于F島的核電站屋确,受9級特大地震影響纳击,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜攻臀,卻給世界環(huán)境...
    茶點故事閱讀 41,080評論 3 327
  • 文/蒙蒙 一焕数、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧刨啸,春花似錦堡赔、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,713評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至仑荐,卻和暖如春雕拼,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背粘招。 一陣腳步聲響...
    開封第一講書人閱讀 32,852評論 1 269
  • 我被黑心中介騙來泰國打工啥寇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 47,865評論 2 370
  • 正文 我出身青樓辑甜,卻偏偏與公主長得像衰絮,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子磷醋,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,689評論 2 354

推薦閱讀更多精彩內(nèi)容