问个 block 申明的问题

saiyagg 发布于 2013年11月21日 | 更新于 2013年11月21日
无人欣赏。

苹果 Block 文档Use Type Definitions to Simplify Block Syntax 部分有如下申明定义,不知道该如何理解:

 void (^(^complexBlock)(void (^)(void)))(void) = ^ (void (^aBlock)(void)) {
     return ^{ };
};

最佳回答将得到我通过支付宝的悬赏 2元

共18条回复
tinyfool 回复于 2013年11月21日

出击皮卡丘 @sycx

adad184 回复于 2013年11月21日

返回值为一个block的block?

adad184 回复于 2013年11月21日

The complexBlock variable refers to a block that takes another block as an argument (aBlock) and returns yet another block.

saiyagg 回复于 2013年11月21日

2楼 @adad184

我有两个疑问:

  • void (^( ^complexBlock )( void (^)(void) )) (void) 从这里可以看出返回值和参数都是void, 但为什么函数体的参数和返回值都是block?
  • void (^( ^complexBlock )( void (^)(void) )) (void) 中的 ( ^complexBlock )( void (^)(void) ) 部分,按照我的理解应该是 block 的 name,此部分该如何理解?
saiyagg 回复于 2013年11月21日

3楼 @adad184

我在文档里也看到过这句话,从函数体的代码来看,这句话是可以理解的;但从声明部分来看,我没有理解。

麻烦对照申明部分的代码解释下文档中的这句话。

adad184 回复于 2013年11月21日
void (^( ^complexBlock )( void (^)(void) )) (void) 

你看有几个^ 就表示有几个block

void (^)(void) 

是block 做为complexBlock的参数

你可以记为 blockArg

void (^( ^complexBlock )( blockArg )) (void) 

( ^complexBlock )( blockArg )

是block的名称和参数部分 记为 blockBody

void (^blockBody) (void)     

这个 就是一个block的定义了

上面的意思是 blockBody的返回值是一个block 参数为void 返回值为void

这是一种C语言的定义方法 类似返回函数指针的函数指针... 就是这个样子..

其实这种写法是可读性非常差的.... 可以用typedef 先预定义block类型 会比较好

typedef void (^argBlock)(void);
typedef void (^returnBlock)(void);

其实文档里也说了 rewrite the code 类似如下

returnBlock (^complexBlock)(argBlock) = ^ (argBlock aBlock) {
    ...
    return ^{
        ...
    };
};
saiyagg 回复于 2013年11月21日

6楼 @adad184

嗯,非常感谢,你的思路很清晰,我也看的差不多了,但还有几个细节需要请教下:

  • 整体 void (^blockBody) (void) 定义中 blockBody 为block的名字,这个应该是个字符串,按照你的理解,这个blockBody 是一个block, 这个点怎么理解?
  • 作为 blockBody 的 ( ^complexBlock )( blockArg),是一个block,对于这点,我的疑问是可以用一个block来做另一个block的名字吗?如果可以,这个block ( ^complexBlock )( blockArg ) 可以不需要申明返回类型吗?
  • void (^blockBody) (void) 这个是整体的结构,可以看出返回值和参数都是void, 那函数体代码中的参数和返回值都是block,这点儿怎么理解呢?
adad184 回复于 2013年11月21日

7楼 @saiyagg

你看一下 http://www.cnblogs.com/zplutor/archive/2013/10/27/3391310.html

基本可以解释这个定义的方法

关于1,2点 blockbody不是名字 而是一种代表而已 原来的写法太拗口 归纳一下就更好理解了

saiyagg 回复于 2013年11月21日

8楼 @adad184

拜读中......

adad184 回复于 2013年11月21日

9楼 @saiyagg 不是我写的 网上找的 :)

这种定义方法 实在是难以阅读 自己写的时候最好还是用typedef的方式

sycx 回复于 2013年11月21日

参考阅读: From C Declarators to Objective-C Blocks Syntax

记住里面提到的阅读申明的方法: when reading complex declarator, you always start from the identifier and go right as long as possible then go left when you reach either the end of the declarator or a closing parenthesis.

对于

void (^(^complexBlock)(void (^)(void)))(void)

1.首先要从complexBlock开始,遵从先往右,后往左的原则,首先提取出来的信息就是:

(^complexBlock) : 说明变量 complexBlock 的类型是 Block

2.在继续就是complexBlock的参数

(^complexBlock) (void (^)(void)): 说明complexBlock的参数是一个block void (^)(void)

3.最后就是complexBlock的返回值

void (^ (^complexBlock)(void (^)(void)) )(void) : complexBlock的返回值是一个block void (^)(void)


PS: 生产环境中要是看到有人写这样的代码,请把他拖出去打一顿

saiyagg 回复于 2013年11月21日

11楼 @sycx

首先感谢大神 @sycx 的回复,对这个的理解终于清晰了:

  • complexBlock 的参数和返回值都是 void (^)(void)
  • 而返回的这个 block, 它的参数和返回值都是 void

是不是有点儿绕。

最佳答案就是 @sycx 的,报上你的支付宝账号吧。 同时感谢 @adad184

tinyfool 回复于 2013年11月21日

12楼 @saiyagg 支付宝,哈哈哈

sycx 回复于 2013年11月21日

12楼 @saiyagg 赞 我的收款主页: sycx

saiyagg 回复于 2013年11月21日

14楼 @sycx 赏金已发放。

sycx 回复于 2013年11月21日

15楼 @saiyagg 哦哦哦 感谢! 我仿佛看到了发家致富的康庄大道!

isaced 回复于 2013年11月21日

这撒钱的提问方式还真不错!

jjjjjeffrey 回复于 2013年11月21日

11楼 @sycx 大神就是大神,专业!

本帖有18个回复,因为您没有注册或者登录本站,所以,只能看到本帖的10条回复。如果想看到全部回复,请注册或者登录本站。

登录 或者 注册
[顶 楼]
|
|
[底 楼]
|
|
[首 页]