Block

基本使用

声明

  • 返回值(^block变量名)(参数)
void(^block)();

定义

第一种
void(^block)() = ^(){

};
第二种
  • 如果没有参数,参数可以隐藏,如果有参数,定义的时候必须要写参数,而且必须要有参数变量名
void(^block)(int) = ^(int a){

};
第三种
  • block返回可以省略,不管有没有返回值,都可以省略
int(^block)() = ^int{
   return 0;
};

类型:int(^)(NSString *)

int(^block)(NSString *) = ^(NSString *name){
   return 0;
};

调用

block();

快捷方式 敲inline直接回车

<#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {
        <#statements#>
    };

block属性

@property (nonatomic, strong) void(^block)();
void(^block)() = ^{

};

开发场景

保存代码

  • 在一个类中定义,在另外一个类中调用
//一个类定义
@property (nonatomic, strong) void(^block)();
//另外一个类调用
item.block = ^{

};

代理传值

传值:
1.只要能拿到对方就能传值

  • 顺传:给需要传值的对象,直接定义属性就能传值
  • 逆传:用代理,block,就是利用block去代替代理
    在这里插入图片描述
  • 我们想让ModalViewControll给ViewControll传值,我们可以使用代理
ModalViewControll类中.h声明
@class ModalViewControll
@protocol ModalViewControllDelegate <NSObject>
@optional
//设计方法:想让代理做什么事情
-(void)modalViewControll:(modalViewControll *)modalVc sendValue:(NSString *)value;
@end
@property(nonatomic, weak) id<ModalViewControllDelegate> delegate;
ModalViewControll类中.m实现
//我们把动作设成点击ModalViewControll控制器给ViewControll传值
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
 //传值给ViewControll
 if ([_delegate respondsToSelector:@selector(modalViewControll:sendValue:)]){
    [_delegate modalViewControll:self sendValue:@"123"];
  }
}
  • 123就是我们给ViewControll传的值
在ViewControll.m中实现
//1.遵守协议<ModalViewControllDelegate>
//2.设置代理为ViewControll控制器
ModalViewControll moadlVc = [[ModalViewControll alloc] init];
modalVc.delegate = self;
//实现代理方法
-(void)modalViewControll:(ModalViewControll *)modalVc sendValue:(NSString *)value{
   NSLog(@"%@", value);
}

block传值(推荐使用block进行逆传值)

ModalViewControll类中.h声明
@property (nonatomic, strong) void(^block)(NSString *value);
ModalViewControll类中.m实现
//我们把动作设成点击ModalViewControll控制器给ViewControll传值
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
 //传值给ViewControll
 if (_block){
   _block(@"123");
 }
}
在ViewControll.m中实现
ModalViewControll moadlVc = [[ModalViewControll alloc] init];
modal.block = ^(NSString *value){
   NSLog(@"%@", value);
};

参数使用

  • 怎么区分参数是block,就看有没有,只要有,把block当作参数
  • 把block当作参数,并不是马上就调用block,什么时候调用,由方法内部决定
  • 什么时候需要把block当作参数去使用:做的事情由外界决定,但是什么时候做由内部决定
需求:封装一个计算器,提供一个计算方法,怎么计算由外界决定,什么时候计算由内部决定

1.创建一个计算器管理者(CacultorManager)

在CacultorManager.h中实现
//用来保存计算的结果
@property(nonatomic,assign) NSInteger result;
-(void)cacultor:(NSInteger (^) (NSInteger result)) block;
在CacultorManager.m中实现
-(void)cacultor:(NSInteger (^)(NSInteger))block{
    if (block) {
       _result = block(_result);
    }
}
在ViewController.m中实现
//创建计算器管理者
    CacultorManager *cacultor = [[CacultorManager alloc] init];
    [cacultor cacultor:^NSInteger(NSInteger result) {
        result += 5;
        return result;
    }];
    NSLog(@"%ld",cacultor.result);

返回值

  • 链式编程思想:把所有的语句用.号连接起来,好处:可读性非常好
- (void)viewDidLoad{
  [super viewDidLoad];
//只有返回值是block,我们才可以写成这个样子调用
  self.test();
}

-(void(^)())test{

   return ^{
   
   NSLog(@"调用了block");
   };

}
需求:封装一个计算器,提供一个计算方法(加法)

1.创建一个计算器管理者(CacultorManager)

在CacultorManager.h中实现
//用来保存计算的结果
@property(nonatomic,assign) NSInteger result;
-(CacultorManager *(^)(int))add;
在CacultorManager.m中实现
return ^(int value){
        _result = _result + value;
        return self;
    };
在ViewController.m中实现
//创建计算器管理者
    CacultorManager *cacultor = [[CacultorManager alloc] init];
    cacultor.add(5).add(5).add(5);
    NSLog(@"%ld",cacultor.result);

内存管理

面试
  • block是一个对象
  • 如何判断当前文件是MRC,还是ARC
    1.dealloc 能否调用super,只有MRC才能调用super
    2.能否使用retain, release。如果能用就是MRC
  • ARC管理原则:只要一个对象没有被强指针修饰就会被销毁,默认局部变量对象都是强指针,存放在堆里面
  • MRC开发常识:
    1.MRC没有strong,weak,局部变量对象就是相当于基本数据类型
    2.MRC给成员属性赋值,一定要使用set方法,不能直接访问下划线成员属性赋值

MRC:管理block

  • 只要是block没有引用外部局部变量,block放在全局区(和环境没有关系)
  • 只要block引用外部局部变量,block放在栈里面
  • block只能使用copy,不能使用retain,使用retain,block还是在栈里面,使用copy在堆里面

ARC:管理block

  • 只要是block没有引用外部局部变量,block放在全局区(和环境没有关系)
  • 只要block引用外部局部变量,block放在堆里面
  • block使用strong,最好不用copy

循环引用

  • block造成循环引用:block会对里面所有强指针变量都强引用一次
  • 解决
@property (nonatomic, strong) void(^block)();
__weak typrof(self) weakSelf = self;
_block = ^{

  NSLog(@"%@", weakSelf);
 
};

变量传递

  • 如果是局部变量,block是值传递
  • 如果是静态变量,全局变量,__block修饰的变量,block都是指针传递
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

iOS开发疯狂者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值