Block 代碼塊 類(lèi)似于指針 指向一塊代碼
Block是Objective C語(yǔ)言中的對(duì)象 但是與NSObject有所區(qū)別 Block是特殊的Objective C對(duì)象
Block 對(duì)象提供了一個(gè)使用 C 語(yǔ)言和 C 派生語(yǔ)言(如 Objective-C 和 C++)來(lái)創(chuàng)建表達(dá)式作為一個(gè)特別的函數(shù)。在其他語(yǔ)言和環(huán)境中,一個(gè)block對(duì)象有時(shí)候被稱(chēng)為“閉包(closure)”。在這里,它們通常被口語(yǔ)化為”塊(blocks)”,除非在某些范圍它們?nèi)菀缀蜆?biāo)準(zhǔn) C 表達(dá)式的塊代碼混淆。對(duì)于閉包(closure),有很多定義,其中閉包就是能夠讀取其它函數(shù)內(nèi)部變量的函數(shù)

圖解
用處
1)簡(jiǎn)單的回調(diào)過(guò)程,不用再實(shí)現(xiàn)并調(diào)用某個(gè)函數(shù)(UIView動(dòng)畫(huà))
2)代碼簡(jiǎn)潔,減少冗余代碼
3)與GCD結(jié)合使用 爽爆了
//帶有參數(shù)的block
void (^YSBlock) (int ,NSString *);
YSBlock = ^(int age,NSString *name){
NSLog(@"年齡:%d 姓名:%@",age,name);
};
YSBlock(20,@"wys");
//無(wú)參數(shù)但有返回值的block,相當(dāng)于閉包
int (^YSBlcok1)();
YSBlock1 = ^(){
int a = 100;
int b = 50;
return a+b;
};
int value = YSBlock();
NSLog(@"oc --- %d",value);
//block在加載局部變量時(shí),會(huì)把局部變量copy成一個(gè)常量存放在block內(nèi)部。并且此常量為只讀的
int a = 10;
void (^block1) () = ^{
NSLog(@"a的值:%d",a);
};
a = 5;
block1();
//如果要在block內(nèi)部修改一個(gè)局部變量,必須在局部變量前加上__block關(guān)鍵字。
__block int b = 5;
void (^block2)() = ^{
b = 10;
};
block2();
//block 內(nèi)部可以對(duì)實(shí)例變量 全局變量,靜態(tài)變量 重新賦值
在self中對(duì)block使用了copy關(guān)鍵字,保留了block的引用計(jì)數(shù),在copy的block內(nèi)部,使用了self的屬性,造成了self引用計(jì)數(shù)增加,此時(shí)造成了循環(huán)引用
/**
* 1.使用property描述block時(shí),要使用copy關(guān)鍵字(從棧中copy到堆中)
* 2.在被copy的block中,如果使用對(duì)象或者對(duì)象的屬性,都會(huì)造成對(duì)象引用計(jì)數(shù)增加。如果要避免此種情況,需要在對(duì)象前加__block關(guān)鍵字 <MRC>
* 3.__weak <ARC>
* 4.創(chuàng)建一個(gè)block時(shí),系統(tǒng)默認(rèn)把block放在全局區(qū) NSGlobalBlock
* 5.當(dāng)block中引用了其他變量,系統(tǒng)會(huì)把此block放到棧上 NSStackBlock
* 6.在棧上的block ,對(duì)其做retain操作是不起任何作用的
*/
block使用例子
// 1. 在第二個(gè)Controller的.h文件中定義block
@property (nonatomic,copy) void(^colorBlock)(UIColor *);
// 2.在第二個(gè)Controller的.m文件中調(diào)用block
-(void)changeColor:(UIButton *)btn
{
self.colorBlock([UIColor yellowColor]);
}
// 3.在第一個(gè)Controller的.m文件中傳遞block的值
-(IBAction)goNext:(id)sender
{
NextVC * nextVc = [[NextVC alloc] init];
__block CurrentVC * curVc = self;
nextVc.colorBlock = ^(UIColor * color){
curVc.view.backgroundColor = color;
};
[self.navigationController pushViewController:nextVc animated:YES];
}
#pragma mark - 檢查網(wǎng)絡(luò) (HTTPManager類(lèi) -> 需要在.h中聲明)
+(void)checkNetWork:(void(^)(NSInteger))blockState
{
//網(wǎng)絡(luò)錯(cuò)誤
blockState(-1);
}
//在別的類(lèi)中就可以這樣使用
//檢查網(wǎng)絡(luò)
[HTTPManager checkNetWork:^(NSInteger statusIndex) {
NSLog(@"當(dāng)前網(wǎng)絡(luò)為 = %ld",statusIndex);
}];
微信公共號(hào):iapp666666
GitHub:點(diǎn)此前往