iOS下的闭包上篇-Block

Posted 搜狐技术产品

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了iOS下的闭包上篇-Block相关的知识,希望对你有一定的参考价值。

   
综上所述:可选的传递某些参数从而实现某些回调功能

/ (a->__forwarding->a) = 12;
  • android自定义ViewGroup的那些事儿

    2021-10-14

    Flutter之美

    2021-10-28

    前端通用SEO技术优化指南

    2021-10-07

    你真的了解符号化么?

    2021-09-16

    ios 中的block应用

    在这个大冬天里默默敲着键盘,勿喷.今天学习swift过程中,学习到闭包,发现闭包和oc的block中有很多的相同之处,又重新学习了一下并且学习了一些高级点的用法,内容如下:

    1.block格式说明:(返回类型)(^块名称)(参数类型) = ^(参数列表) {代码实现};//如果没有参数,等号后面参数列表的()可以省略
    例子:

    void(^demoBlock)() = ^ {

        NSLog(@"demo Block");

    };

    int(^sumBlock)(int, int) = ^(int x, int y) {

        return x + y;

    };

     

    2.block中使用的变量将以复制的形式保留,在block中保留block的复制的变量,默认情况下,Block外部的变量,在Block中是只读的!当使用__block关键字后,同样可以在Block中修改外部变量的数值.
     
    3.可以使用typedef定义一个Block的类型,便于在后续直接使用,如:

    typedef double(^MyBlock)(double, double);

    MyBlock area = ^(double x, double y) {

        return x * y;

    };

    MyBlock sum = ^(double a, double b) {

        return a + b;

    };

    NSLog(@"%.2f", area(10.0, 20.0));

    NSLog(@"%.2f", sum(10.0, 20.0));

    4.尽管,typedef可以简化Block的定义,但在实际开发中并不会频繁使用typedef关键字,这是因为Block具有非常强的灵活性,尤其在以参数传递时,使用Block的目的就是为了立即使用
    官方的数组遍历方法声明如下:

    - (void)enumerateObjectsUsingBlock:(void (^)(id obj, NSUInteger idx, BOOL *stop))block;

    而如果使用typedef,则需要:
    (1)typedef void(^EnumerateBlock)(id obj, NSUInteger idx, BOOL *stop);
    (2)- (void)enumerateObjectsUsingBlock:(EnumerateBlock)block;

    而最终的结果却是,除了定义类型之外,EnumerateBlock并没有其他用处

     
    5.Block可以被当做参数直接传递

    NSArray *array = @[@"张三", @"李四", @"王五", @"赵六"];

    [array enumerateObjectsUsingBlock:^(id obj, NSUInteger idx, BOOL *stop) {

        NSLog(@"第 %d 项内容是 %@", (int)idx, obj);

        if ([@"王五" isEqualToString:obj]) {

            *stop = YES;

        }

    }];

     

    或者:

    MyBlock sumBlock = ^(double x, double y) {
        return x * y;
        
    };

    - (void)add:(int)number withNumber:(int)withNumber sumBlock:(MyBlock) block
    {
       
        NSLog(@"执行add:(int)number withNumber:(int)withNumber sumBlock:(void (^)(void))block");
        NSLog(@"hahaha--4和2相乘等于:%f",block(number,withNumber));

    }

       [self add:4 withNumber:2 sumBlock:sumBlock];

     

    6.既然Block是一种数据类型,那么可以将Block当做比较特殊的对象,添加到数组

    #pragma mark 定义并添加到数组

    @property (nonatomic, strong) NSMutableArray *myBlocks;

    int(^sum)(int, int) = ^(int x, int y) {

        return [self sum:x y:y];

    };

    [self.myBlocks addObject:sum];

    int(^area)(int, int) = ^(int x, int y) {

        return [self area:x y:y];

    };

    [self.myBlocks addObject:area];

    #pragma mark 调用保存在数组中的Block

    int(^func)(int, int) = self.myBlocks[index];

    return func(x, y);

     

    7.解除循环引用

    局部变量默认都是强引用的,离开其所在的作用域之后就会被释放
     
    使用__weak关键字,可以将局部变量声明为弱引用

    __weak DemoObj *weakSelf = self;

    n在Block中引用weakSelf,则Block不会再对self做强引用

    int(^sum)(int, int) = ^(int x, int y) {

        return [weakSelf sum:x y:y];

    };

     

    8.今天重点,参考AFN的框架,block根据函数判断正确与否调用success或者failure函数参数,并传入参数.如下:

    //由于主要还是用来判断success和failure函数,所以看着不舒服的同学可以自行脑补,将success换成add,将failure换成multiplied

    - (void)viewDidLoad {
        [super viewDidLoad];
        self.isbool = true;//当isbool等于true的时候就相加,否则就相乘
     
        [self setCompletionBlockWithSuccess:^(int x,int y) {
            NSLog(@"相加等于:%d",x+y);
           
           NSLog(@"success");
       
           
        } failure:^(int x,int y) {
            
            NSLog(@"相乘等于:%d",x*y);
            NSLog(@"failure");
            
        
        }];

    }


    - (void)setCompletionBlock:(void (^)(void))block {
     
            block();
        NSLog(@"setCompletionBlock number2:%d number3:%d",self.number2,self.number3);
    }


    - (void)setCompletionBlockWithSuccess:(void (^)(int x,int y))success
                                  failure:(void (^)(int x,int y))failure
    {

         self.completionBlock = ^{
        
             self.number2 = 10;
             self.number3 = 20;
        

             if (self.isbool == true) {//判断传入哪个参数,执行success还是failure
                 NSLog(@"开始相加");
                 success(self.number2,self.number3);//参数传入setCompletionBlockWithSuccess
             }else{
                  NSLog(@"开始相乘");
                 failure(self.number2,self.number3);//参数传入setCompletionBlockWithSuccess
             }
         };


    }

     

     

     

     

     
     

    以上是关于iOS下的闭包上篇-Block的主要内容,如果未能解决你的问题,请参考以下文章

    ios block 类型

    IOS多线程之Block编程

    Swift 闭包 与 OC block区别

    ios开发之block的使用,及注意事项

    swift学习第十五天:闭包

    swift中闭包的使用(类似与block的做法) 闭包传值