• iOS block分析


    block是代码块,其本质和变量类似。不同的是代码块存储的数据是一个函数体。使用Block,就可以像其他标准函数一样,传入参数,并得到返回值。

    可以把Block当做Objective-C的匿名函数,Block允许开发者在两个对象之间将任意的语句当做数据进行传递,block的实现具有封闭性(closure),而又能够很容易获取上下文的相关状态信息。 

    Block使用场景,可以在两个界面的传值,也可以对代码封装作为参数的传递等。

    ARC情况下
      1.如果用copy修饰Block,该Block就会存储在堆空间。则会对Block的内部对象进行强引用,导致循环引用。内存无法释放。

    解决方法:
      新建一个指针(__weak typeof(Target) weakTarget = Target )指向Block代码块里的对象,然后用weakTarget进行操作。就可以解决循环引用问题。

      2.如果用weak修饰Block,该Block就会存放在栈空间。不会出现循环引用问题。

    MRC情况下
      用copy修饰后,如果要在Block内部使用对象,则需要进行(__block typeof(Target) blockTarget = Target )处理。在Block里面用blockTarget进行操作。

      默认情况下,Block内部不能修改外面的局部变量。
      Block内部可以修改使用__block修饰的局部变量。

    1、无参数无返回值的Block

    /**
         *  void :就是无返回值
         *  emptyBlock:就是该block的名字
         *  ():这里相当于放参数。由于这里是无参数,所以就什么都不写
         */
        void (^emptyBlock)() = ^(){
            NSLog(@"无参数,无返回值的Block");
        };
        emptyBlock();

    2、有参数无返回值的Block

    /**
         *  调用这个block进行两个参数相加
         *
         *  @param int 参数A
         *  @param int 参数B
         *
         *  @return 无返回值
         */
        void (^sumBlock)(int ,int ) = ^(int a,int b){
            NSLog(@"%d + %d = %d",a,b,a+b);
        };
        /**
         *  调用这个sumBlock的Block,得到的结果是20
         */
        sumBlock(10,10);

    3、有参数有返回值的Block

    /**
         *  有参数有返回值
         *
         *  @param NSString 字符串1
         *  @param NSString 字符串2
         *
         *  @return 返回拼接好的字符串3
         */    
        NSString* (^logBlock)(NSString *,NSString *) = ^(NSString * str1,NSString *str2){
            return [NSString stringWithFormat:@"%@%@",str1,str2];
        };
        //调用logBlock,输出的是 我是Block
        NSLog(@"%@", logBlock(@"我是",@"Block"));
    Block结合typedef使用

    自己定义一个Block类型,用定义的类型去创建Block,更加简单便捷。

    /**
     *  定义了一个changeColor的Block。这个changeColor必须带一个参数,这个参数的类型必须为id类型的
     *  无返回值
     *  @param id
     */
    typedef void(^changeColor)(id);
    /**
     *  用上面定义的changeColor声明一个Block,声明的这个Block必须遵守声明的要求。
     */
    @property (nonatomic, copy) changeColor backgroundColor;
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        //声明一个颜色
        UIColor *color = [UIColor redColor];
        //用刚刚声明的那个Block去回调修改上一界面的背景色
        self.backgroundColor(color);
    }
    -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
        ViewController2 *vc =[[ViewController2 alloc]init];
        // 回调修改颜色
        vc.backgroundColor = ^(UIColor *color){
            self.view.backgroundColor = color;
        };
        [self.navigationController pushViewController:vc animated:YES];
    }

    iOS-block三种应用场景

    • 1.把block保存成对象中的属性,在恰当的时刻调用

    2.把block当成方法的参数使用,block的调用在是在方法内部,在外界写block的实现(最常用)

    3.把block当成方法的返回值(比较少用)

    示例1

    1.在Person类中

    @interface Person : NSObject
    @property (nonatomic,strong) void(^myBlock)(int,int);
    @end

    2.在ViewController类中

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        int a = 12;
        int b = 11;
        Person *p = [[Person alloc] init];
        p.myBlock(a,b);
    }

    示例2

    1.在Person类中

    @interface Person : NSObject
    - (void)eat:(void(^)())block;
    @end
    
    @implementation Person
    - (void)eat:(void (^)())block
    {
        block();
    }
    @end

    2.在ViewController类中

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
        // 方式1.先定义,在赋值
        //    void(^block)() = ^() {
        //        NSLog(@"吃东西");
        //    };
        //
        //    [p eat:block];
    
        // 方式2.直接写block
        [p eat:^{
            NSLog(@"吃东西");
        }];
    }

    示例3

    1.在Person类中

    @interface Person : NSObject
    - (void(^)(int))run;
    @end
    
    @implementation Person
    - (void (^)(int))run
    {
        return ^(int b){
            NSLog(@"跑了--%d米",b);
        };
    }
    @end

    2.在ViewController类中

    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
    {
         p.run(5);
    }
  • 相关阅读:
    HTTPS
    RPC
    2017.4.19上午
    2017.4.18下午
    2017.4.18上午
    2017.4.17下午
    2017.4.17上午
    2017.4.14下午
    2017.4.14上午
    2017.4.13下午
  • 原文地址:https://www.cnblogs.com/fengmin/p/6134542.html
Copyright © 2020-2023  润新知