- 很久之前就想怎么用好block,面试的时候也被问到block会不会用,用的多么。。。感觉block用起来特帅有木有。。。
- 自我感觉,一个iOS程序员中级低级分水岭就在于,会不会用block。一段代码好不好,最直观的体验就是1,方法封装了没,2,block用的多不多。。。(个人意见,不喜勿喷)
今天系统写了些关于block的一些变量定义跟方法调用
首先,block到底怎么用,什么时候用,怎么才能想到去用,应该是一个新手程序员最头疼的问题
- block就像一个小弟一样,谁要用的时候,叫过来,让block过一遍就好了,跟函数的方法一样,block里的具体内容,在调用之前写好,在调用的时候才会执行。
- delegate就是委托,A委托给B去执行,告诉B执行什么,B还需要签署一个委托书,相对而言是很麻烦的。
下面,为具体给出一个block简单的具体写法,让大家感受一下大体的流程
- 第一个demo
要求:
我们首先创建两个控制器,第一个控制器的页面上有一个label和一个按钮A,第二个控制器的页面上有一个textField和一个按钮B,在textField上随便输入一串文字,点击按钮B,跳转会第一个页面,讲输入的文字展示在label上。
思路:
把这个赋值操作当作小弟(block)
我们一边整理思路,一边上代码
- 1.首先,点击第二个控制器的按钮B,需要让label的文字改变,我们把label改变看作block,在点击按钮的时候调用
#import <UIKit/UIKit.h>
// 给block起个名儿
typedef void(^blockBack)(NSString *tf);
@interface NextViewController : UIViewController
/** block,注意block用copy修饰,但是不带“*”号 */
// strong也可以,但是建议copy
@property (nonatomic, copy) blockBack tfblock;
@end
#import "NextViewController.h"
@interface NextViewController ()
@property (weak, nonatomic) IBOutlet UITextField *tf;
@end
@implementation NextViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
}
// 点击按钮
- (IBAction)sentTo:(id)sender {
// 叫小弟(block)过来,让他做事
if (_tfblock != nil) {
NSString *str = _tf.text;
_tfblock(str);
}
[self dismissViewControllerAnimated:YES completion:^{}];
}
@end
- 2.小弟(block)要做的事是讲textField上的文字赋给label,所以,我们应该在拿到label的那个控制器做事情,也就是说,
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
// 拿到第二个页面,让label.text = textField
// 这个赋值运算就是小弟(block)干的事儿
NextViewController *vc = segue.destinationViewController;
vc.tfblock = ^(NSString *str){
_label.text = str;
};
}
- 3.这样我们整个流程就走通了,想法其实很简单,控制器B想执行赋值操作,但是拿不到A的label,所以叫了一个含有label赋值代码的小弟
(block)过来执行。
上面这个demo有个很明显的弊端,就是我们在写这些block的时候,全程手打所有的符号,这样很不方便,所以,我们来写第二个demo,利用回调
要求:
控制器上有个按钮,点击按钮,让他颜色改变成固定颜色,
思路:
把这个改变颜色事件当成一个做事的小弟(block)
- 1.写一个类,继承NSObjected写这个block事件
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
// 定义一个block,取个名儿
typedef void(^ChangeColor)(UIColor *color);
@interface ColorBtn : NSObject
// 直接写回调方法,把这个block当做参数传出,不用单独定义block
+ (void)ChangeViewBtnColor:(ChangeColor)changeColorBlock;
@end
#import "ColorBtn.h"
@implementation ColorBtn
+ (void)ChangeViewBtnColor:(ChangeColor)changeColorBlock
{
NSLog(@"进来了");
// color参数传出
UIColor *color = [UIColor redColor];
// 调用block做事
changeColorBlock(color);
}
@end
- 2.在控制器里面的按钮点击方法中执行这个block
- (IBAction)colorBtn:(id)sender {
[ColorBtn ChangeViewBtnColor:^(UIColor *color) {
[_colorBtn setBackgroundColor:color];
}];
}
- 3.搞定,回调的写法就是能省区很多手打的内容,全程提示默认,很方便
可能看着有点混乱,但是基本就是这么个思路,把block想成小弟来看,就能了解到什么时候考虑去用这个block了