zoukankan      html  css  js  c++  java
  • iOS开发-Objective-C Block的实现方式

    前言:我们可以把Block当作一个闭包函数,它可以访问外部变量和局部变量,但默认是不可以修改外部变量。你可以使用它来做回调方法,比起使用代理(Delegate)会更加直观。顺带一提,苹果很多的接口(API)都使用了Block。

    一、Block的基本定义

    Block的基本写法(也是详细写法):

    returnType (^blockName)(params) = ^returnType(params) {
        // code... 
    };

    中文再解释:返回类型 (^Block的名字)(Block的参数) = ^返回类型(Block的参数) { 这里放代码 },例:

    int (^myBlock)(int num1, int num2) = ^int(int num1, int num2){
        return 100;
    };

    如果你的Block不需要返回类型和参数,那么你可以简写为:

    void (^myBlock2)() = ^(){
        
    };

    void (^myBlock2)(void) = ^void(void){
        
    };

    返回类型或参数,没有的话可以用“void”代替。

    你也可以把等于号右边,^后的()删除,即是:

    void (^myBlock2)() = ^{
        
    };

    这样是不是很简洁?

    你也可以先定义一个Block函数,但不写函数的实现,我们可以在后面再写具体函数的实现,像这样:

    void (^myBlock2)(void);
    myBlock2 = ^{
        
    };

    二、Block作为方法定义

    把Block定义在方法里,与上面不同的是,Block的名字不需要在声明时写上,而是在后面,像这样:

    - (void)getWtihBlock:(void (^)())block
    {
        // code...
        
        // 记得要调用block
        block();
    }

    使用方法:

    [self getWtihBlock:^{
        NSLog(@"sdf");
    }];

    下面作了一个详细点的例子,并写了备注:

    /**
     *  追加自身字符串N次(每次复制前加一个换行
    )
     *
     *  @param string      字符串
     *  @param count       追加次数
     *  @param stringBlock 目标Block,其中str参数为结果字符串
     */
     // Block也可以定义在方法里,但是不需要定义Block的名字
     // IOS开发很多的API也用到了Block,像UIView的块动画
    - (void)getStrWithString:(NSString *)string
                   CopyCount:(int)count
                resultString:(void (^)(NSString *str))stringBlock
    {
        NSMutableString *newString = [NSMutableString stringWithString:string];
        for (NSUInteger i = 0; i < count; i++) {
            NSUInteger len = [string length];
            NSString *insertString = [NSString stringWithFormat:@"
    %@", string];
            [newString insertString:insertString atIndex:len];
        }
        // 调用block,传入字符串newString
        stringBlock(newString);
    }

    用法也是一样:

    BlockObject *block = [[BlockObject alloc] init];
    [block getStrWithString:@"Garvey"
                  CopyCount:3
               resultString:^(NSString *str) {
                   // str为处理后的结果
                   NSLog(@"str is %@", str);
               }];

    有时候复杂的Block语法会令到函数的声明难以阅读,所以会经常使用typedef对Block起一个新类型。

    typedef void (^ResultBlock)(NSString *str);

    定义方法时就变成了:

    - (void)getStrWithString2:(NSString *)string
                    CopyCount:(int)count
                 resultString:(ResultBlock)stringBlock;

    让我们对比一下,使用typedef前后:

    // 使用前
    - (void)getStrWithString:(NSString *)string
                   CopyCount:(int)count
                resultString:(void (^)(NSString *str))stringBlock;
    
    // 使用后
    - (void)getStrWithString2:(NSString *)string
                    CopyCount:(int)count
                 resultString:(ResultBlock)stringBlock;

    注意:使用方法是一样的,只不过定义变得简单了。

    如果你一直在使用代理(Delegate)进行方法回调,那么你现在可以尝试使用Block了。


    博文作者:GarveyCalvin

    博文出处:http://www.cnblogs.com/GarveyCalvin/

    本文版权归作者和博客园共有,欢迎转载,但须保留此段声明,并给出原文链接,谢谢合作!

  • 相关阅读:
    MD5 Message Digest Algorithm in Visual Basic 6
    遍历指定文件夹的指定格式的文件并且copy到指定的文件夹下面
    宝宝的成长脚印8/17
    儿歌童谣两首
    office2003之資料編輯列的角字顯示7/10
    宝宝的成长脚印8/27
    宝宝的成长脚印7/30
    宝宝的成长脚印7/3
    LED手电筒真不咋滴8/27
    液晶显示器右边出现黑条7/7
  • 原文地址:https://www.cnblogs.com/GarveyCalvin/p/4204167.html
Copyright © 2011-2022 走看看