Objective-C中的块语法(以及我假设的C语言)非常不协调。将块作为参数传递与声明块作为实例变量不同,这与使用typedef
定义块不同。
是否有一个全面的块声明语法列表可供参考?
Objective-C中的块语法(以及我假设的C语言)非常不协调。将块作为参数传递与声明块作为实例变量不同,这与使用typedef
定义块不同。
是否有一个全面的块声明语法列表可供参考?
在整个过程中,让:
return_type
是您想返回的对象/原始类型等的类型(通常为 void
)blockName
是您正在创建的块的变量名称var_type
是您要作为参数传递的类型对象/原始类型等(如果不需要参数,则留空)varName
是所给定参数的变量名称记住您可以创建尽可能多的参数。
可能是最常见的声明形式。
return_type (^blockName)(var_type) = ^return_type (var_type varName)
{
// ...
};
类似于将块声明为变量,但略有不同。
@property (copy) return_type (^blockName) (var_type);
请注意,这与“块作为参数”不同;在这种情况下,您声明的是需要一个块参数的方法。
- (void)yourMethod:(return_type (^)(var_type))blockName;
注意这与“块作为参数”不同;在此情况下,您正在调用需要匿名块作为参数的方法。如果您已经声明了一个块变量,则将变量名称作为参数传递即可。
[someObject doSomethingWithBlock: ^return_type (var_type varName)
{
//...
}];
从功能上而言,这实际上是一个匿名块,但将块分配给变量的语法只需要将变量设置为匿名块。
^return_type (var_type varName)
{
//...
};
typedef
块这允许您设置一个短名称,可以在块声明期间像任何其他类名一样被引用。
typedef return_type (^blockName)(var_type);
如果想要在后面使用 blockName
而不是标准的块声明语法,只需替换即可。
这可能是块的一个较少使用的方式,但仍然有其应用价值。内联块是指实例化后立即调用的匿名块。
^return_type (var_type varName)
{
//...
}(var);
内联块主要用于作用域偏移,与简单的大括号分隔的代码块大致等效。
{
//...
}
使用递归块,您可以从自身调用一个块,创建在回调和GCD调用期间使用的循环。此实例化方法在ARC中不会产生保留周期。
__block return_type (^blockName)(var_type) = [^return_type (var_type varName)
{
if (returnCondition)
{
blockName = nil;
return;
}
// ...
} copy];
blockName(varValue);
一个方法可以返回一个 block,
- (return_type(^)(var_type))methodName
{
// ...
}
如果有点奇怪的话,函数也可以这样做。
return_type (^FunctionName())(var_type)
{
// ...
}
如果我遗漏了任何内容,请在评论中告诉我,我会进行研究并添加它们。
blockName = (varName: var_type) -> (return_type)
这几乎就像是一种语言特性。
我个人喜欢使用这个网站 (http://fuckingblocksyntax.com)。这个名字比块语法本身更容易记忆:
如果您无法加载带有不良词汇的网址,则可以使用此镜像:http://goshdarnblocksyntax.com
类型定义:
typedef void (^block)(NSString *arg);
内联:
void (^block)(NSString *) = ^(NSString *param) {
// do something....
};
方法:
- (void)method:(void (^)(NSString *param))handler
Xcode 4的片段库中包含用于块typedef和作为变量的内联块的模板。它们还可以通过自动补全(typedefblock
和inlineblock
)使用。
对于作为方法参数的块,我建议声明一个typedef
,然后简单地使用它。这使得代码更易于阅读。
我为一个类编写了一个completionBlock,它将在摇动骰子后返回其值:
在 @interface
声明上方的 .h
文件中定义带有返回类型的 typedef。
typedef void (^CompleteDiceRolling)(NSInteger diceValue);
在块的.h
文件中定义一个@property
。
@property (copy, nonatomic) CompleteDiceRolling completeDiceRolling;
定义一个具有finishBlock
方法的函数(.h
)。- (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock;
将之前定义的方法插入到 .m
文件中,并将 finishBlock
提交给之前定义的 @property
。- (void)getDiceValueAfterSpin:(void (^)(NSInteger diceValue))finishBlock{
self.completeDiceRolling = finishBlock;
}
为了触发completionBlock
,将预定义的变量类型传递给它
(不要忘记检查completionBlock
是否存在)
if( self.completeDiceRolling ){
self.completeDiceRolling(self.dieValue);
}
typedef void (^OkBtnBlock)(id data);
typedef void (^CancelBtnBlock)();
@property (nonatomic, strong) OkBtnBlock okBtnBlock;
@property (nonatomic, strong) CancelBtnBlock cancelBtnBlock;
+ (void)foo:(OkBtnBlock)okBtn andCancel:(CancelBtnBlock)btnCancel;
@property (copy) return_type (^blockName) (var_type);
@property blockName;
@property blockName
没有起作用。我认为应该是 @synthesize blockName;
才对(用于合成一个 block)。 - jeet.chanchawat