我有一个像这样定义的块:
CGPoint (^rotateOrderedPair)(CGFloat, CGFloat, CGFloat, CGFloat, CGFloat) = ^(CGFloat x, CGFloat y, CGFloat pivotX, CGFloat pivotY, CGFloat angle) {
CGFloat rotatedX = cos(angle) * (x - pivotX) - sin(angle) * (y - pivotY) + pivotX;
CGFloat rotatedY = sin(angle) * (x - pivotX) + cos(angle) * (y - pivotY) + pivotY;
return CGPointMake(rotatedX, rotatedY);
};
我想问为什么在这个世界上我必须写(CGFloat, CGFloat, CGFloat, CGFloat, CGFloat)
什么时候所有命名参数的列表后面只有几个字符?为何如此欺骗?我一定错过了一些明显的东西。
答案 0 :(得分:3)
人们通常会键入任何非平凡的块,这使得这几乎不是问题:
typedef CGPoint (^XYPointTransform)(CGFloat, CGFloat, CGFloat, CGFloat, CGFloat);
然后:
XYPointTransform rotateOrderedPair =
^(CGFloat x, CGFloat y, CGFloat pivotX, CGFloat pivotY, CGFloat angle) {
// …
});
从代码可读性的角度来看,typedef也是可取的。此外,声明和定义中的签名不必完全相同:
typedef void (^SomeBlock)(NSObject*);
SomeBlock foo = ^(id arg) {…};
这意味着你不会重复两次完全相同的东西,并且在实际的块定义中选择稍微不同的类型的可能性有时很方便。
我同意进行某种类型推断会很好:
auto block = ^(/* a complex signature*/) {…};
据我所知,这不存在。
答案 1 :(得分:0)
块的语法很大程度上是基于C函数指针的语法建模的,所以你应该在那个世界中寻找基本原理。