码迷,mamicode.com
首页 > 其他好文 > 详细

学习笔记-block基本使用

时间:2016-05-07 13:00:04      阅读:193      评论:0      收藏:0      [点我收藏+]

标签:

基本使用:作用就是用来保存一段代码块
在一个方法定义,在另外一个方法去调用(用的少,可以用定义方法替代)
一般在 在一个类中定义,在另外一个类中去调用 用的比较多
-------------------------------------------------------------------------------------------Make by - ljw 转载请注明出处---  
定义的几种方式:
方式一: 等号 = ^(参数){ block代码块 }
注意点:如果block带有参数,在定义的时候,一定要有参数,并且变量名不能省略
 
    void(^block1)(int) = ^(int a){
        NSLog(@"调用了block%d",a);
    };
   
   
方式二: 如果没有参数,参数可以省略
    void(^block2)() = ^{
       
    };
   

 

方式三: 等会右边 = ^返回值(参数),返回值可以省略,不管有没有返回值,都可以省略
注意:如果Block有返回值,block代码块必须要有返回值
    int(^block3)() = ^int{
        return 1;
    };

 

-------------------------------------------------------------------------------------------  
调用block1:查看block保存的代码
    block1(2);
 
block快捷方式:inline
//    <#returnType#>(^<#blockName#>)(<#parameterTypes#>) = ^(<#parameters#>) {
//        <#statements#>
//    };

 

   
案例:点击cell,作出相应的动作
在cell里面利用block保存代码
1.在cell模型声明block属性
@property (nonatomic, strong) void(^block)();

 

2.在模型里面保存代码
    // 打电话
    CellItem *item = [CellItem cellItem];
    item.title = @"打电话";
    // 定义block给它
    item.block = ^{
        NSLog(@"打电话");
    };

 

3.点击cell调用block
// 点击cell就会调用
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    CellItem *item = self.items[indexPath.row];
   
    if (item.block) {
        item.block();
    }
}

 


block传值:
    顺传:定义属性
    逆传:代理, block替代代理
 
    传值万能步骤:A传值B,A拿到B 就能传值  B传值A,拿到B就能传值
方式一:代理
 
方式二:block
1.在传递方头文件声明block属性
@property (nonatomic, strong) void(^block)(NSString *value);

 

 
2.在.m文件触发事件传值(参数)
判断一下是否有block
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    // 传值:
    if (_block) {
       _block(@"123");
    }

 

3.接收方拿到传递方,拿到block接收值
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    ModalViewController *modalVc = [[ModalViewController alloc] init];
   
    modalVc.block = ^(NSString *value){
        NSLog(@"利用了block,接收到值%@",value);
    };

 

 

block内存管理
  如何判断当前项目是ARC,还是非ARC
    1.在ARC中,不允许调用retain,release,retainCount
    2.重写dealloc,ARC中不能调用[super dealloc]
   
    怎么进入非ARC环境 : 点击工程文件 -> buildSetting -> ARC
 
 技术分享
    在非ARC开发注意点:访问属性,一定要使用get,set方法,不能直接使用下划线
 
block是对象吗?
是!官方文档有说明.可以放到数组或者字典中使用!
看官方文档
(搜索working with Blocks)
 
 
非ARC  block内存
只要block访问了外部变量,生命周期不是全局的(是否在代码块里面),就存放在栈里面
生命周期是全局的,block就存放在全局区
只要Block没有访问外部变量,就放在全局区
 
非ARC内存管理:
block在非ARC中必须要使用copy  
Block为什么用copy,在非ARC
在非ARC环境下,retain相当于strong,为什么block不用retain
因为在非arc中,是不会存放到堆里面,过了代码块就会被释放.再访问就会坏内存访问报错
 
非ARC
是没有strong的(强指针)的
不能用下划线直接访问成员属性的
 
在非ARC开发注意点:访问属性,一定要使用get,set方法,不能直接使用下划线
 
----------------------------------------------------------------------------------------------------------------------------------
ARC内存管理:
ARC下,默认一个局部变量就是一个强指针,防止一创建就释放
block访问了一个局部变量,就会放到堆里面
 
能用strong就用strong,因为copy内部会做很多事情
 
    只要访问了一个外部变量,,生命周期不是全局的,只会放在堆里面
    只要访问了一个外部变量,,生命周期是全局的,只会放在全局区
 
把一个控制器modal出来,再dismiss会把控制器销毁
 
 
只要在block代码块里面使用了self强引用就会导致循环引用
注意:只要在block的代码中,访问外部强指针对象,就会把对象强引用
 1 - (void)viewDidLoad {
 2     [super viewDidLoad];
 3     int a = 2;
 4    
 5     // 注意:只要在block的代码中,访问外部强指针对象,就会把对象强引用
 6     /// 解决循环引用
 7     // block
 8     __weak typeof(self) weakSelf = self;
 9    
10     _block = ^{
11       
12         // 定义强指针的self
13         __strong typeof(self) strongSelf = weakSelf;
14        
15         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
16            
17             NSLog(@"%@",strongSelf);
18            
19         });
20        
21        
22         NSLog(@"%d",a);
23        
24     };
25    
26     _block();
27 }

 

block在定义的时候就把值传进去了
值传递: 访问局部变量
指针传递:访问生命周期全局变量
被__block修饰的局部变量,就是指针传递
 
 
bock开发场景:参数使用
1.封装一个类的时候,有些时候,怎么去做由外界决定,但是由内部决定什么时候调用,把block当做一个参数去使用.
 
动画block:做什么样的动画由我们决定,但是什么时候调用由系统决定.
 
 

 
block当做返回值
链式编程思想: 把所有的方法调用全部通过.语法连接起来,好处:可读性非常好
mgr.add(5).add(5);
其实是分两步走,先调用mgr.add的getter,返回一个block.再跟着()实现这个block
 
- (CalculatorManager *(^)(int))add;
 
- (CalculatorManager *(^)(int))add
{
    return ^(int value){
       
        _result += value;
       
        return self;
    };
}

 

 
- (void)add;
实现:mgr.add()
想实现小括号,必须是两步走,先实现block的getter
—>- (void *(^)(int))add;
实现:mgr.add(5).add(5)
想继续点下去,就必须得有一个返回值
—>- (CalculatorManager *(^)(int))add;
 
题外话:装逼写法:block实现里面后面直接跟着调用
    ^{
        NSLog(@"调用");
    }();
 
 
 
 
 
 
 

学习笔记-block基本使用

标签:

原文地址:http://www.cnblogs.com/ljwios/p/5467826.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!