zoukankan      html  css  js  c++  java
  • block注意事项

    1.block的声明和注意事项

    #import "ZYViewController.h"
    
    @interface ZYViewController ()
    
    @end
    
    /*用typedef可以声明一种类型的block*/
    
    //block前加上typedef, 那么就不是一个block指针(变量),而是一种block类型
    //给int (^) (int a, int b) 这种block类型 声明了一个别名,叫做Block5
    typedef int (^Block5) (int a, int b);
    
    //Block6就是无参无返回的block的类型
    typedef void (^Block6) (void);
    
    @implementation ZYViewController
    
    
    - (void)viewDidLoad
    {
        [super viewDidLoad];
                
        //block
        //原理:block也是指针,指向的不是对象的内存地址,而是一段代码块的地址
        
        //void/*返回类型*/ (^/*代表是指针类型*/ block1/*变量名*/) (void/*参数*/) = NULL/*初值为空*/;
        
        //无参无返回的block,如果无参,参数可以写void,也可以不写
        void (^block1) (void) = NULL;
        //block1的类型  void (^) (void) 无参无返回的类型
        //给block赋值,无参的block赋值,在=后可以写成^(void)、^()、^,如果不是无参的,那么必须把参数类型和形参名写完整
        block1 = ^(void) {
            NSLog(@"hello world");
        };
        //执行block
        block1();
        
        
        //有参无返回
        //void (^block2) (int)中的(int)只是声明该block参数的个数,以及每个参数的类型,在声明的时候可以不写形式参数,但是在实现的时候必须写形式参数,而且实现时的形式参数名可以和声明时不同
        void (^block2) (int n) = ^(int n) {
            NSLog(@"------>%d", n);
        };
        block2(222);
        
        //多参无返回,每个参数之间用","分割,在执行的时候需要注意参数的顺序
        void (^block3) (int age, NSString *name) = ^ (int age, NSString *name) {
            NSLog(@"%@今年 %d岁", name, age);
        };
        block3(1000, @"龟小妹");
        
        //有参有返回
        int (^block4) (int a, int b) = ^(int a, int b) {
            return a + b;
        };
        int sum = block4(1, 7);
        NSLog(@"--------->%d", sum);
        
        Block5 block5 = NULL;
        block5 = ^(int a, int b) {
            return a + b;
        };
        int sum1 = block5(100, 1);
        NSLog(@"--------->%d", sum1);
        
        
        //基本数据类型
        //1.对于局部的不添加“__block”的基本数据类型,block用到的是对变量的值的拷贝,在block中对变量赋值没用意义
        //2.对于局部的添加“__block”的基本数据类型,block中不会对变量的值进行拷贝,可以在block中对变量进行赋值
        //3.对于全局基本数据类型的变量,除了作用范围不同外,其他的同添加“__block”的局部变量
        __block int num = 0;
        NSLog(@"地址1----->%p", &num);
        void (^block6) (void) = ^(void) {
            NSLog(@"1**************  %d", num);
            NSLog(@"地址2----->%p", &num);
            num = 20;
        };
        num = 10;
        NSLog(@"2**************===  %d", num);
        NSLog(@"地址3----->%p", &num);
        block6();
        NSLog(@"3**************===  %d", num);
        
        
        //指针类型
        //1.对于不添加“__block”的局部指针,block中用到的是指针的拷贝,可以用此拷贝的指针去更改对象的属性,但是不能直接更改对象
        //2.对于添加“__block”的局部指针,block中不会对指针进行拷贝,可以更改对象
        //3.对于全局的指针,除了作用范围外,其他同添加“__block”的局部指针
        __block ZYTest *test = [[ZYTest alloc] init];
        //NSLog(@"1----->%@---->%p", test, &test);
        //NSLog(@"1----->%@", test.date);
        void (^block7) (void) = ^(void) {
            NSLog(@"2----->%@---->%p", test, &test);
            test = [[ZYTest alloc] init];
            test.date = [NSDate date];
            NSLog(@"2----->%@", test.date);
        };
        
        //NSLog(@"3----->%@---->%p", test, &test);
        NSLog(@"3----->%@", test.date);
        block7();
        NSLog(@"4----->%@---->%p", test, &test);
        NSLog(@"5----->%@", test.date);
        
            
    }

    2.block的内存问题

     //1.block变量的copy,不会增加全局的或者是添加“__block”的局部指针的引用计数
        //2.block变量的copy,会把不添加“__block”的局部指针指向的对象retain一次
        NSDate *date = [NSDate date];    
        void (^tempBlock) (int n) = ^(int n) {
            //NSLog(@"专业测试语句,请勿模仿-->%d", n);
            NSLog(@"2---->%d", date.retainCount);
        };
        block1 = [tempBlock copy];
        //block1(50);
        //NSLog(@"3---->%d", date.retainCount);
        
        
        self.block2 = ^(void) {
            NSLog(@"======专业测试语句,请勿模仿");
        };
        
        
        __block ZYViewController *tempSelf = self;
        NSLog(@"1----->self.retainCount=%d", self.retainCount);
        void (^block3) (void) = ^(void) {
            [tempSelf test];
            NSLog(@"2----->self.retainCount=%d", tempSelf.retainCount);
        };
        self.block2 = block3;
        _block2();
        NSLog(@"3----->self.retainCount=%d", self.retainCount);



    #import <UIKit/UIKit.h>
    #import "ZYSecViewController.h"

    @interface ZYViewController : UIViewController
    {
        //声明一个全局的block,因为block声明在栈上,所以对于全局的block赋值要添加一个copy,把其拷贝到堆上,而且在dealloc中要添加该block的释放语句
        void (^block1) (int n);
        
        NSDate *now;
        
    }

    //采用这种方式也可以声明一个全局的block,自动生成的block变量带一个"_",描述的时候要用copy,如果在其他类中需要使用block作为一个属性,则必须要@property描述
    @property(nonatomic, copy)void (^block2) (void);


  • 相关阅读:
    Python与机器视觉(x)图像修复
    git push代码到远程新分支
    1024节日快乐~~~~
    【Python-GPU】GPU数据科学加速包——RAPIDS
    Echarts漂亮水滴图
    【深度学习】三维点云数据集总结
    poj 3273 Monthly Expense
    poj 3150 Cellular Automaton
    poj 3101 Astronomy
    hdu 4282 A very hard mathematic problem
  • 原文地址:https://www.cnblogs.com/keyan1102/p/4480634.html
Copyright © 2011-2022 走看看