定義1:web
等號右邊:^(參數類型 參數變量名){ }; 無返回值:(void)(^block)() = ^(){ };
定義2:面試
等號右邊:^返回值(參數類型 參數變量名){ };返回值能夠省略,可是也有不省略 無返回值:(void)(^block)() = ^void(){ }; 有返回值:int(^block3)(int a) = ^int(int a){ return 2; };
定義3:編程
等號右邊:當沒有返回值,沒有參數,能夠省略 無返回值:(void)(^block)() = ^{ };
//block的聲明 @property (nonatomic, strong) void(^block)(); //block的定義 void (^block)() = ^{ NSLog(@"daquan"); }; //block的手動調用 block(); --------------------------------- // name:block類型別名 typedef void(^BlockType)(); //聲明 @property (nonatomic, assign) BlockType block1; //定義 _block1 = ^{ NSLog(@"daquan"); }; //調用 _block1();
無返回值無參數:void(^block)() = ^{}; 無返回值有參數:void(^block)(NSString *str) = ^(NSString *str){ }; 有返回值有參數:int(^block)(int a) = ^int(int a) {}; 有返回值無參數:int(^block)() = ^int(){};
inlineblock:快速生成block代碼
異步
returnType(^blockName)(parameterTypes) = ^(parameters) { statements };
傳值的方式:ide
1.順傳:定義屬性 2.逆傳:代理,block.block能夠用來替代代理,實現相同的功能.
實例:點擊主控制器後,就modal另外一個控制器,並將modal出來控制器裏面的值傳遞給主控制器. 主控制器: #import "ViewController.h" #import "ModalViewController.h" @interface ViewController ()<ModalViewControllerDelegate> - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { // 建立modal控制器 ModalViewController *modalVc = [[ModalViewController alloc] init]; modalVc.delegate = self; [self presentViewController:modalVc animated:YES completion:nil]; } #pragma mark -ModalViewControllerDelegate - (void)modalViewController:(ModalViewController *)modalVc sendValue:(NSString *)value { NSLog(@"%@",value); } @end modal出來的控制器: #import <UIKit/UIKit.h> //聲明類 @class ModalViewController; //定義協議 @protocol ModalViewControllerDelegate <NSObject> //建立方法(可實現,可不實現) @optional //將字符串傳遞出去 - (void)modalViewController:(ModalViewController *)modalVc sendValue:(NSString *)value; @end @interface ModalViewController : UIViewController //代理屬性 @property (nonatomic, weak) id<ModalViewControllerDelegate> delegate; @end //點擊事件 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { //須要判斷是否實現了代理方法 if ([_delegate respondsToSelector:@selector(modalViewController:sendValue:)]) { [_delegate modalViewController:self sendValue:@"123"]; } // 回到上一個控制器(modal出來的控制器就能夠用dismiss回到上一個控制器) [self dismissViewControllerAnimated:YES completion:nil]; }
主控制器: - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { // 建立modal控制器 ModalViewController *modalVc = [[ModalViewController alloc] init]; modalVc.valueBlock = ^(NSString *value){ NSLog(@"%@",value); }; [self presentViewController:modalVc animated:YES completion:nil]; } modal出來的控制器: @property (nonatomic, strong) void(^valueBlock)(NSString *value); - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event { // 傳值 if (_valueBlock) { _valueBlock(@"123"); } // 回到上一個控制器 [self dismissViewControllerAnimated:YES completion:nil]; }
總結:atom
8.1.MRC:(沒有strong,weak,只有assign,retain,copy)url
面試題:block是否是對象? --> 是(官方文檔:working with blocks) 1.手動管理內存,須要本身去釋放內存. 2.開發習慣:訪問屬性或者設置屬性,必須使用點語法(會調用get方法),不要使用下劃線. 3.區分MRC代碼:看可否調用release、retain;ARC不能調用[super dealloc]; 4.修改配置信息:ARC automatic...= NO;(在工程文件中搜索ARC便可找到) 5.如何管理block? 內存5個區:堆,棧,方法區,常量區,全局區 堆:手動管理內存 棧:自動管理,代碼塊一過,就會自動釋放 5.1MRC中,若是block沒有訪問外部的局部變量或者局部變量被static修飾,block默認存放在"全局區" 5.2MRC中,不能使用retain聲明block,依然放在棧裏面,會自動銷燬 5.3MRC中,使用copy聲明block,纔會放在堆裏面. 5.4MRC中,默認一個對象就是基本類型.
8.2.ARC:spa
ARC管理原則:默認一個局部變量對象,都是強指針,存放在堆裏面;若是沒有一個對象沒有強指針引用,就會銷燬. 1.若是block訪問外部的局部變量,block默認存放在"堆"裏面 2.使用strong聲明block,不要使用weak. 3.block會對外部全部強指針對象給強引用.不會對外部的弱指針給強引用.
// 聲明weakSelf弱指針 __weak typeof(self) weakSelf = self; _block = ^{ NSLog(@"%@",weakSelf); }; //dealloc方法 - (void)dealloc { NSLog(@"%s",__func__); }
_block = ^{ // 延遲操做或者異步任務,才須要搞個strongSelf __strong typeof(weakSelf) strongSelf = weakSelf; dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{ NSLog(@"%@",strongSelf); }); }; _block();
11.1.何時使用block充當參數?思想3d
封裝一個功能,這個功能作什麼事情由外界決定,可是何時調用由內部決定,這時候就須要把block充當參數去使用.
11.2.怎麼去把block充當參數?實戰代理
11.3.鏈式編程思想:把方法調用經過點語法連接,可讀性很是好
11.4.封裝一個計算器,提供一個加法語法.
11.5.block做爲參數的實現
CalculatorManage: #import <Foundation/Foundation.h> @interface CalculatorManage : NSObject @property (nonatomic, assign) int reslut; - (int)calculator:(int(^)(int result))block; @end @implementation CalculatorManage - (int)calculator:(int (^)(int result))block { _reslut = block(_reslut); return _reslut; } 主控制器: @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; CalculatorManage *mgr = [[CalculatorManage alloc] init]; [mgr calculator:^(int result) { result += 5; result *= 2; return result; }]; NSLog(@"%d",mgr.reslut); } 輸出結果:10