Block概念介紹
block是一段代碼塊,是一個(gè)對(duì)象
Block的聲明
返回值(^block變量名)(參數(shù))
void(^block)();
Block的定義
// block定義:三種方式 = ^(參數(shù)){};
// 第一種
void(^block1)() = ^{
NSLog(@"調(diào)用了block1");
};
// 第二種 如果沒有參數(shù),參數(shù)可以隱藏,如果有參數(shù),定義的時(shí)候,必須要寫參數(shù),而且必須要有參數(shù)變量名
void(^block2)(int) = ^(int a){
};
// 第三種 block返回可以省略,不管有沒有返回值,都可以省略
int(^block3)() = ^int{
return 3;
};
// block類型:int(^)(NSString *)
int(^block4)(NSString *) = ^(NSString *name){
return 2;
};
// block調(diào)用
block1();
Block的快捷定義:
block快捷方式 inline
<#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {
<#statements#>
};
Block開發(fā)使用
BlockType:類型別名
typedef void(^BlockType)();
block怎么聲明,就如何定義成屬性
@property (nonatomic, strong) void(^block)();
@property (nonatomic, strong) BlockType block1;
Block的傳值:順傳草穆,逆?zhèn)?/p>
Block的內(nèi)存管理
-
切換MRC與ARC環(huán)境
E6C65D26-9806-4D2A-BFFD-C4A8178E446C.png -
如何判斷當(dāng)前環(huán)境是MRC還是ARC只壳?
- dealloc 能否調(diào)用super,只有MRC才能調(diào)用super
- 能否使用retain,release.如果能用就是MRC
-
無(wú)論MRC還是ARC
只要block沒有引用外部局部變量,block放在全局區(qū)
MRC下的Block應(yīng)用
-
MRC了解開發(fā)常識(shí)
- MRC沒有
strong``weak
,局部變量對(duì)象就是相當(dāng)于基本數(shù)據(jù)類型
- MRC給成員屬性賦值,一定要使用set方法,不能直接訪問下劃線成員屬性賦值
- MRC沒有
-
MRC:管理block
- 總結(jié):只要block沒有引用外部局部變量,block放在全局區(qū)
NSGlobalBlock
void(^block)() = ^ { NSLog(@"在全局區(qū)"); }; block(); NSLog(@"%@", block);
- 只要Block引用外部局部變量,block放在棧里面
NSStackBlock
int d = 90; void(^block)() = ^ { NSLog(@"在棧區(qū)%d", d); // 引用了外部局部變量 }; block(); NSLog(@"%@", block);
- block只能使用copy,不能使用retain,使用retain,block還是在棧里面
5E5910AD-4C03-47A4-91D1-DB65468AF5F4.png421EEE13-8D8D-41AE-BF6F-ADC6455E26ED.pngAFD77458-7CA2-4819-8674-2D69F066F1EC.png - 總結(jié):只要block沒有引用外部局部變量,block放在全局區(qū)
ARC下的Block應(yīng)用
-
ARC管理原則
- 只要一個(gè)對(duì)象沒有被強(qiáng)指針修飾就會(huì)被銷毀,默認(rèn)局部變量對(duì)象都是強(qiáng)指針,存放到堆里面
只要block引用外部局部變量,block放在堆里面
block使用strong.最好不要使用copy
-
__block的應(yīng)用
0CFC6848-8669-407E-81E4-0C5E2DFC20B4.png4BBDECA7-78B5-45E5-BCF8-B0F162FD6B0B.png4C3A28D5-3E5F-4F63-B535-57528D359C6C.png
E85D2796-5DF3-4A43-9370-911CED719DC7.png
循環(huán)引用
- 循環(huán)引用:我引用你,你也引用,就會(huì)造成循環(huán)引用,雙方都不會(huì)被銷毀,導(dǎo)致內(nèi)存泄露問題
- block造成循環(huán)利用:Block會(huì)對(duì)里面所有強(qiáng)指針變量都強(qiáng)引用一次
_block = ^{
NSLog(@"%@",self); //造成循環(huán)引用
}
_block();
__weak typeof(self) weakSelf = self;
_block = ^{
NSLog(@"%@",weakSelf); //沒有循環(huán)引用
};
_block();
__weak typeof(self) weakSelf = self;
_block = ^{
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"%@",weakSelf); // 如果在2s內(nèi)dismissViewController(想要銷毀vc),則此處打印為nil
});
};
_block();
__weak typeof(self) weakSelf = self;
_block = ^{
__strong typeof(weakSelf) strongSelf = weakSelf;
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"%@",strongSelf);// 所以在block內(nèi)再strongSelf此處打印為當(dāng)前vc洪燥,當(dāng)前vc會(huì)在執(zhí)行完當(dāng)前block之后再銷毀阻塑,也就是dismiss時(shí)vc不銷毀歉眷,10s后執(zhí)行了代碼后vc會(huì)自動(dòng)銷毀
});
};
_block();
變量傳遞
- 如果是局部變量,Block是值傳遞
- 如果是靜態(tài)變量,全局變量,__block修飾的變量,block都是指針傳遞
__weak __typeof(self)weakSelf = self;
static int a = 3; //靜態(tài)變量
self.b = 2; //全局變量
int c = 3; //局部變量,值傳遞
__block int d = 5; //__block修飾
NSString *name = @"name"; //局部變量
__block NSString *text = @"text"; //__block修飾
void (^testBlock)() = ^ {
NSLog(@"a = %d, b = %d, c = %d, d = %d, name = %@,
text = %@", a, weakSelf.b, c, d,name, text);
};
a = 10;
self.b = 10;
c = 10;
d = 10;
name = @"hello";
text = @"world";
testBlock();
結(jié)果:
a = 10, b = 10, c = 3, d = 10, name = name, text = world
Block作為參數(shù)
CalculatorManager *mgr = [[CalculatorManager alloc] init];
[mgr plus:^NSInteger(NSInteger result) {
return result + 3;
}];
// CalculatorManager
- (void)plus:(NSInteger (^)(NSInteger value))addBlock {
if (addBlock) {
_resulte = addBlock(_resulte);
}
}
鏈?zhǔn)骄幊?/h3>
CalculatorManager *mgr = [[CalculatorManager alloc] init];
//mgr.div (3),mgr.div返回block材诽,block的參數(shù)是3
mgr.div(3).div(1).div(2);
//返回Block
- (CalculatorManager * (^)(NSInteger value))div{
return ^(NSInteger value){ // 返回值為block
_resulte = _resulte / value;
return self; //block的返回類型為CalculatorManager
};
}
其他
- Block在MRC中就是基本數(shù)據(jù)類型
- ARC的局部變量默認(rèn)都是強(qiáng)指針
- 為什么ARC中局部變量默認(rèn)是強(qiáng)指針底挫?為了在代碼塊中不被銷毀,
- Block用weak什么時(shí)候銷毀
- Block在ARC中用Strong
- manager item
CalculatorManager *mgr = [[CalculatorManager alloc] init];
//mgr.div (3),mgr.div返回block材诽,block的參數(shù)是3
mgr.div(3).div(1).div(2);
//返回Block
- (CalculatorManager * (^)(NSInteger value))div{
return ^(NSInteger value){ // 返回值為block
_resulte = _resulte / value;
return self; //block的返回類型為CalculatorManager
};
}