ios block回调的理解和总结
来源:互联网 发布:知乎2018校园招聘 编辑:程序博客网 时间:2024/06/05 09:12
1) IOS常用回调方式有3种,如:delegate、NSNotificationCenter和block。
2) 通知:
(一对多)在APP中,很多控制器都需要知道一个事件,应该用通知;
3) delegate:
“一对一”,对同一个协议,一个对象只能设置一个代理delegate,所以单例对象就不能用代理;block没有协议方法,也不需要delegate代理对象
代理更注重过程信息的传输:比如发起一个网络请求,可能想要知道此时请求是否已经开始、是否收到了数据、数据是否已经接受完成、数据接收失败
4) block:
写法更简练,不需要写protocol、函数等等
block注重结果的传输:比如对于一个事件,只想知道成功或者失败,并不需要知道进行了多少或者额外的一些信息
一对一,与代理类似,但是block没有协议方法,也不需要delegate代理对象
block需要注意防止循环引用:
ARC下这样防止:__weak typeof(self) weakSelf = self;
[yourBlock:^(NSArray *repeatedArray, NSArray *incompleteArray) {
[weakSelf doSomething];
}];
补充: 这三种通信方式都实现了对象之间的解耦合。(解耦合就是两个对象建立了一种通信关系,但是它们没有关联得特别紧。也可以说是他们没有依赖于某一个对象)
2. 什么情况下使用block回调或delegate回调
1) 公共接口,方法较多也选择用delegate进行解耦(iOS有很多例子比如最常用tableViewDelegate,textViewDelegate)
2) 异步和简单的回调用block更好 (iOS有很多例子比如常用的网络库AFNetwork,ASIHTTP库,UIAlertView类)
3) 它们都是为了在具体的实现Delegate或Block中再进行处理,属于策略模式,具体算法在具体算法类中实现。
3. block回调的设计步骤
1) 先声明: #type void(^MyBlock) (int a,int b)
2) 定义声明的block
{
[super viewDidLoad];
[self blockTest:^(int a, int b) {
int c = a + b;
NSLog(@"步骤2:%i",c); //回调函数,这里是先执行步骤1的函数
}];
}
3) 调用block
{
NSLog(@"步骤1");
myBlock(10,20);
}
4. block回调例子
1) 例子1:
* 需求:在cell上添加一个Button,点击时跳转到ShowNameViewController控制器
* 已知:cell上无法使用push方法,这个时候可以在cell上添加一个block回调,然后在MainViewController上使用push方法,从而达到跳转的目的
*/
//MainViewController.h
#import <UIKit/UIKit.h>#import "ShowNameViewController.h"@interface MainViewController : UIViewController<UITableViewDataSource,UITableViewDelegate>{ UITableView *_tableView;}@end
//MainViewController.m
#import "MainViewController.h"#import "NameListTableViewCell.h"@interface MainViewController ()@end@implementation MainViewController- (id)init{ self = [super init]; if (self) { self.title = @"玩家列表"; } return self;}- (void)viewDidLoad { [super viewDidLoad]; _tableView =[[UITableView alloc]initWithFrame:CGRectMake(0, 0,320.0f,480.0f) style:UITableViewStylePlain]; _tableView.allowsSelection = NO; _tableView.separatorStyle = UITableViewCellSeparatorStyleNone; //分割线隐藏 _tableView.dataSource = self; _tableView.delegate = self; [self.view addSubview:_tableView];}#pragma mark -- UITableViewDelegate- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{ return 1;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{ static NSString *identity = @"identityCell"; NameListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identity]; if (cell == nil) { cell = [[NameListTableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identity]; } cell.textLabel.text = @" "; //实现NameListTableViewCell中的pushToBlock [cell setPushToBlock:^{ [self pushToVC]; NSLog(@"MainVC"); }]; /* 或者这样也行 cell.pushToBlock = ^{ [self pushToVC]; NSLog(@"MainVC"); }; */ return cell;}- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{ return 200;}- (void)pushToVC{ ShowNameViewController *showVC = [[ShowNameViewController alloc]init]; [self.navigationController pushViewController:showVC animated:YES];}@end
//NameListTableViewCell.h
#import <UIKit/UIKit.h>#import "ShowNameViewController.h"#import "MainViewController.h"typedef void(^PushToBlock)(void);@interface NameListTableViewCell : UITableViewCell@property (nonatomic,copy) PushToBlock pushToBlock;@end
//NameListTableViewCell.m
#import "NameListTableViewCell.h"@implementation NameListTableViewCell- (void)awakeFromNib {}- (void)setSelected:(BOOL)selected animated:(BOOL)animated { [super setSelected:selected animated:animated];}- (void)layoutSubviews{ [super layoutSubviews]; UIButton *startBtn = [UIButton buttonWithType:UIButtonTypeCustom]; startBtn.frame = CGRectMake(60, 100, 200, 30); [startBtn setBackgroundImage:[UIImage imageNamed:@"singBtn_image"] forState:UIControlStateNormal]; [startBtn setTitle:@"查找" forState:UIControlStateNormal]; [startBtn addTarget:self action:@selector(startAction) forControlEvents:UIControlEventTouchUpInside]; startBtn.layer.masksToBounds = YES; startBtn.layer.cornerRadius = 2.5; [self.contentView addSubview:startBtn];}//鼠标点击后执行回调- (void)startAction{ if (self.pushToBlock) { self.pushToBlock(); NSLog(@"回调函数"); }}@end
//ShowNameViewController.h
#import <UIKit/UIKit.h>@interface ShowNameViewController : UIViewController@end
//ShowNameViewController.m
@implementation ShowNameViewController- (void)viewDidLoad { [super viewDidLoad]; self.view.backgroundColor = [UIColor greenColor];}- (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated.}@end
---------------------------------------------------------------------------------------------------------
2) 例子2:
/**
* 需求:点击按钮后,在UIView中增加一个新的view视图和view对应的颜色(一个矩形)
* 在声明block的时候,参数中加入View颜色
*/
//MainViewController.h#import <UIKit/UIKit.h>typedef void(^ViewBlock)(UIColor *color,CGRect rect);@interface MainViewController : UIViewController/** * 将block作为参数传给该函数,从而用来改变视图的size和color * * @param viewBlock block名 */+ (void)changeViewSizeAndColor:(ViewBlock)viewBlock;@end
//MainViewController.m
#import "MainViewController.h"@interface MainViewController ()@end@implementation MainViewController- (id)init{ self = [super init]; if (self) { self.title = @"玩家列表"; } return self;}- (void)viewDidLoad { [super viewDidLoad]; UIButton *startBtn = [UIButton buttonWithType:UIButtonTypeCustom]; startBtn.frame = CGRectMake(60, 100, 200, 30); [startBtn setBackgroundImage:[UIImage imageNamed:@"singBtn_image"] forState:UIControlStateNormal]; [startBtn setTitle:@"查找" forState:UIControlStateNormal]; [startBtn addTarget:self action:@selector(startAction) forControlEvents:UIControlEventTouchUpInside]; startBtn.layer.masksToBounds = YES; startBtn.layer.cornerRadius = 2.5; [self.view addSubview:startBtn];}- (void)startAction{ [MainViewController changeViewSizeAndColor:^(UIColor *color, CGRect rect) { NSLog(@"步骤2"); self.view.backgroundColor = [UIColor orangeColor]; UIView *view = [[UIView alloc]init]; view.frame = rect; view.backgroundColor = color; [self.view addSubview:view]; }];}+ (void)changeViewSizeAndColor:(ViewBlock)viewBlock{ NSLog(@"步骤1"); UIColor *tempColor = [UIColor redColor]; CGRect tempRect = CGRectMake(130, 180, 80, 80); viewBlock(tempColor,tempRect);}@end
例子3:
最简单的例子
void (^myBlock)(int a,int b); myBlock = ^(int a,int b){ NSLog(@"result:%d",a + b); //然后回调 步骤2 NSLog(@"start2"); }; NSLog(@"start1"); myBlock(10,20); //先执行这里 步骤1 //最后输出为: /* start1 result:30 start2 */
//例子3:
让某个方法延时执行
double delayInSeconds = 10; dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC); dispatch_after(popTime, dispatch_get_main_queue(), ^{ [self setImageURL]; });
- ios block回调的理解和总结
- iOS 代理和block的理解
- iOS block的理解
- iOS-block的总结
- iOS-Block的总结
- iOS通俗易懂的Block理解和概括和一道题目
- iOS 对于block的理解
- iOS笔记-(Block的理解)
- iOS 对于block的理解
- 对block的理解总结
- 我对IOS中代理和block的理解
- iOS 的Block 代理模式和回调
- iOS 简单易懂的 Block 回调使用和解析
- block和split的理解
- Block 的理解和使用
- block回调的一点个人理解
- 对iOS中Block的理解
- iOS Block 的理解与学习
- vs2012打包部署时“cannot extract icon with index 0 from file xxx.exe”的解决方案
- 利用python的sklearn开源包进行文本挖掘
- BZOJ 2506 calc
- Struts2 详解
- 解决Hessian【hessian-4.0.7.jar】不能正确传输BigDecimal问题
- ios block回调的理解和总结
- yii2中验证码的添加
- jquery鼠标放上去显示悬浮层即弹出定位的div层
- java面试算法汇总
- 【BZOJ3893】【Usaco2014 Dec】Cow Jog 乱搞
- TCP/UDP端口扫描(多线程应用-仅处于理论状态)-java
- C# .net 简单的点击小图显示大图。
- node PM2 简介
- 关于latch的说明