我在使用名为TransitionKit的库(帮助您编写状态机)时遇到了一种情况,我希望以回调的形式提供进入和退出操作。
可悲的是,回调包括两个完全无用的参数。典型的块必须如下所示:
^void (TKState *state, TKStateMachine *stateMachine) {
// I TOTALLY don't want parameters `state` or `stateMachine` used here
};
(这是一个匿名代码块。如果您不清楚,请阅读块here)
正如我在评论中所指出的那样,我真的不希望那些参数甚至在身体中提到。我试过简单地删除像this question中建议的参数名称,如下所示:
^void (TKState *, TKStateMachine *) {
// I foobar all I like here
};
但遗憾的是代码无法编译:(。
如何在代码中强制执行此类参数的使用?
答案 0 :(得分:2)
这是我能想到的。相当糟糕并且依赖于GCC poison
编译指示,这不是标准的,而是GNU扩展 - 尽管如果你可能用clang
编译它,它应该不是问题。
#define _state state
#define _stateMachine stateMachine
#pragma GCC poison state stateMachine
然后编译:
^(TKState *_state, TKStateMachine *_stateMachine) {
do_something();
}
但这不是:
^(TKState *_state, TKStateMachine *_stateMachine) {
do_something(state, stateMachine);
}
答案 1 :(得分:1)
你可以拥有一个带有一种块的函数,并返回另一个块,如下所示:
@class TKState, TKStateMachine; // here so this will compile
typedef void (^LongStateBlock)(TKState *state, TKStateMachine *stateMachine);
static inline LongStateBlock Adapter(void(^block)()) {
void(^heapBlock)() = [block copy]; // forces block to be on heap rather than stack, a one-time expense
LongStateBlock longBlock = ^(TKState *s __unused, TKStateMachine *sm __unused) {
heapBlock();
};
// this is the non-ARC, MRR version; I'll leave ARC for the interested observer
[heapBlock release];
return [[longBlock copy] autorelease];
}
在实践中:
// this represents a library method
- (void)takesLongStateBlock:(LongStateBlock)longBlock
{
// which hopefully wouldn't look exactly like this
if (longBlock) longBlock(nil, nil);
}
- (void)yourRandomMethod
{
[self takesLongStateBlock:^(TKState *state, TKStateMachine *stateMachine) {
NSLog(@"Gratuitous parameters, AAAAHHHH!");
}];
[self takesLongStateBlock:Adapter(^{
NSLog(@"So, so clean.");
})];
}
整个事情是gisted,应该在任何类中编译。当您拨打-yourRandomMethod
时,它会按预期执行。
答案 2 :(得分:0)
AFAIK在创建块时无法执行所需的操作,在声明块变量时(参考块,以避免误解),您只能错过参数名称。
所以在这里你可以错过参数名称:
void (^myBlock)(SomeClass *);
但是当你创建一个块时不是这样:
myBlock = ^(SomeClass *o)
{
};
答案 3 :(得分:0)
我会写
^void (TKState *unused_state, TKStateMachine *unused_stateMachine) {
// Anyone using unused_state or unused_stateMachine gets what they deserve.
};
当然有人可以使用这些参数。但无论你做什么,他们都可以改变代码。如果有人打算用脚射击自己,就没有阻止它们。