第六章 块与大中枢派发—第38条:为常用的块类型创建typedef

每个块都具备其"固有类型",因而可将其赋给适当类型的变量。这个类型由块所接受的参数及其返回值组成。

^(BOOL flag, int value){
    if (flag) {
        return value * 5;
    } else {
        return value * 10;
    }
}

此块接受两个类型分别为BOOL及int的参数,并返回类型为int的值。如果想把它赋给变量,则需注意其类型。变量类型及相关赋值语句如下:

int (^variableName)(BOOL flag, int value) = ^(BOOL flag, int value){
    // Implementation
    return someInt;
}

这个类型似乎和普通的类型大不相同,然而如果习惯函数指针的话,那么看上去就会觉得眼熟了。块类型的语法结构如下:

return_type (^block_name)(parameters);

与其他类型的变量不同,在定义块变量时,要把变量名放在类型之中,而不要放在右侧。这种语法非常难记,也非常难懂。鉴于此,应该为常用的块类型起个别名,尤其是打算把代码发布成API供他人使用时,更应这样做。开发者可以起个更为易读的名字来表示块的用途,而把块的类型隐藏在其后面。
为了隐藏复杂的块类型,需要用到C语言中名为"类型定义"(type definition)的特性。typedef关键字用于给类型起个已读的别名。比方说,想定义新类型,用以表示接受BOOL及int参数并返回int值的块,可通过下列语句来做:

typedef int(^EOCSomeBlock)(BOOL flag, int value);

声明变量时,要把名称放在类型中间,并在前面加上"^"符号,而定义新类型时也得这么做。上面这条语句向系统中新增了一个名为EOCSomeBlock的类型。此后,不用再以复杂的块类型来创建变量了,直接使用类型即可:

EOCSomeBlock block = ^(BOOL flag, int value) {
    //Implementation
};

这样代码读起来就顺畅多了: 与定义其他变量时一样,变量类型放在左边,变量名放在右边。
通过这项特性,可以把使用块的API做的更为易用些。类里面有些方法可能需要用块来做参数,比如执行异步任务时所用的"completion handler"(任务完成后所执行的处理程序)参数就是块,凡遇到这种情况,都可以通过定义别名使代码变得更为易读。比方说,类里有个方法可以启动任务,它接受一个块作为处理程序,在完成任务之后执行这个块。若不定义别名,则方法签名会像下面这样:

- (void)startWithCompletionHandler:(void(^)(NSData *data, NSError *error))completion;

注意,定义方法参数所用的块类型语法,又和定义变量时不同,若能把方法签名中的参数类型写成一个词,那读起来就顺口多了。于是,可以给参数类型起个别名,然后使用此名称来定义:

typedef void(^EOCCompletionHandler)(NSData *data, NSError *error);
- (void)startWithCompletionHandler:(EOCCompletionHandler)completion;

使用类型定义还有个好处,就是当你打算重构块的类型签名时会很方便。比方说,要给原来的completion handler块再加一个参数,用以表示完成任务所花的时间,那么只需修改类型定义语句即可:

typedef void(^EOCCompletionHandler)(NSData *data, NSTimeInterval duration, NSError *error);

修改之后,凡是使用了这个类型定义的地方,比如方法签名等处,都会无法编译,而且报的都是同一种错误,于是开发者可据此逐个修复。若不用类型定义,而直接写块类型,那么代码中要修改的地方就更多了。开发者很容易忘掉其中一两处,从而引发难于排查的bug。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 《编写高质量iOS与OS X代码的52个有效方法》--第六章 第38条(ps:此乃读书笔记,加深记忆,仅供大家参考...
    z_zero阅读 262评论 0 0
  • importUIKit classViewController:UITabBarController{ enumD...
    明哥_Young阅读 4,024评论 1 10
  • 第六章 block与GCD “块”(block)是一种可在C、C++及Objective-C代码中使用的“词法闭包...
    Code_Ninja阅读 1,106评论 2 4
  • 文:落下絮 本故事纯属虚构 李小萌第一次看见张小燕,是张小燕转学来的那天。下着雨,老师在讲台上介绍新来的转学生,别...
    落下絮阅读 359评论 0 2
  • 2017-9-24(19/99) 感恩 —— 做了金色之光冥想,提升能量,净化磁场。 感恩 —— 客厅也用上了香薰...
    慢慢花开阅读 262评论 0 0