zoukankan      html  css  js  c++  java
  • Block使用总结

    block的使用总结:如果有感觉任何遗漏的话,欢迎留言补充,Block的循环使用那部分,这里我只贴出了解决方案,注意点应该是没有问题的

    Block的使用

        int a = 10;
        NSLog(@"1-----------%d     %p",a,&a);
        void(^block)(void) = ^{
            NSLog(@"2-----------%d  %p",a,&a);
        };
        a = 20;
        block();
        NSLog(@"3-----------%d     %p",a,&a);
    
    

    输出结果:

     

    结论:

    从输出结果可以看出block内和block外是两个作用域,内部的指针a和外部的指针a虽然名字一样但他们的内存地址已经不同了,这也就是我们可以内部修改局部变量的原因。在block内部会将局部变量的指正复制一份,这样内部和外部就不是一个指针了,就算你重新给内部指针赋值,也无法改变外部指针的指向,他们只是名字相同。
      __block int a = 10;
        NSLog(@"1-----------%d     %p",a,&a);
        void(^block)(void) = ^{
            NSLog(@"2-----------%d  %p",a,&a);
        };
        a = 20;
        block();
        NSLog(@"3-----------%d     %p",a,&a);
    

    输入结果

    结论:

    没有通过__block修饰则是将值传进去,而通过__block修饰之后是将变量的内存地址传进去,这样就可以修改变量的值。

    static int a = 10;
        NSLog(@"1-----------%d     %p",a,&a);
        void(^block)(void) = ^{
            NSLog(@"2-----------%d  %p",a,&a);
            a = 30;
        };
        a = 20;
        block();
        NSLog(@"3-----------%d     %p",a,&a);
    

     输入结果:

    结论:静态变量的内存地址一致,所以可以修改变量的值

    _a = 10;
        NSLog(@"1-----------%d     %p",_a,&_a);
        void(^block)(void) = ^{
            NSLog(@"2-----------%d  %p",_a,&_a);
        };
        _a = 20;
        block();
        NSLog(@"3-----------%d     %p",_a,&_a);
    

     输出结果

    结论:全局变量的内存地址一致,所以可以修改变量值

    总结:1.如果block访问的外部变量是局部变量,那么就是值传递,外界改了,不会影响里面
         2.如果block访问的外部变量是__block或者static修饰,或者全局变量,那么就是指针传递,block里面的值和外界属于同一变量,外界改变,里面也会改变 
    

    以上都是无返回值的Block,可以举例一个有返回值的block

     // 先定一个block函数
        int (^sumFunction)(int a, int b) = ^(int x, int y)
        {
            return (x + y);
        };
        NSLog(@"--------------:%d",sumFunction(2, 3));//5
        
    

    如果这个block经常用到,在可以外部定义一个block

    typedef int(^sumFunction)(int a, int b);
    

     在内部使用

    // 先定一个block函数
        sumFunction sum = ^(int x, int y)
        {
            return (x + y);
        };
        NSLog(@"--------------:%d",sum(2, 3));//5
    

    block在fun的使用

    +(void)sumFunctionWithA:(int)a withB:(int)b withBlock:(void (^)(int sum))sumBlock{
        int sum = a+b;
        sumBlock(sum);
    }

    全局的block在fun的使用

     定义:

    typedef void(^SumBlock)(int sum);
    
    +(void)sumFunctionWithA:(int)a withB:(int)b withBlock:(SumBlock)sumBlock{
        int sum = a+b;
        sumBlock(sum);
    }
    
    [ViewController sumFunctionWithA:2 withB:4 withBlock:^(int sum) {
            NSLog(@"---------------------------:%d",sum);//6
        }];
    

    外部调用

    [ViewController sumFunctionWithA:2 withB:4 withBlock:^void(int sum) {
            NSLog(@"--------------------:%d",sum);//6
        }];
    

    Block作为一个属性进行传值,比方A跳转到B页面,B页面个A传值

    在B页面设置Block的全局,在.h的属性方法里设置,这里只写了一个全局的,property一定要用copy,因为block的存在栈上,需要copy到堆上才能我们才能对block的内存进行管理

    typedef void(^SumBlock)(int sum);
    
    @interface ViewController : UIViewController
    @property(nonatomic,copy)SumBlock sumBlock;
    @end

     在B页面需要传值的时间里面调用,一定要加if,不然可能会出现错误

     在A页面跳转B页面的使用使用:这里的vc.sumBlock如果不写,B页面一定需要加if,不然报错

     

    Block的注意事项 

    在block内部使用外部指针且会造成循环引用的的情况下,需要使用

     __weak typeof(self)weakSelf = self;
    

     如果在block内部调用了延迟函数如果还是用弱指针则会取不到指针,因为已经会销毁了,则需要使用强指针在引用一次

    __strong  typeof(self)strongSelf = weakSelf;
    
  • 相关阅读:
    Jenkins安装(一)
    Ansible(一) 安装与简单测试
    zabbix中文乱码
    mysql5.7免密登录
    Zabbix 监控 Nginx 模板
    zabbix通过snmp监控主机
    zabbix5.0+grafana 使用脚本安装
    Eth-trunk配置-LACP模式
    Eth-Trunk配置-手动模式
    文件系统简单理解与实操(ext4)
  • 原文地址:https://www.cnblogs.com/hualuoshuijia/p/11403779.html
Copyright © 2011-2022 走看看