26

我在一些示例代码中看到了下面的语法,但不确定我是否理解它。

 CGRect imageRect = (CGRect){.size = baseImage.size};

这是否只是初始化CGRect等价物的简写方式:

 CGRect imageRect = CGRectMake(0,0,baseImage.size.width, baseImage.size.height);

除了稍微少一点打字之外,这种语法还有什么好处吗?

4

3 回答 3

43

那是C99 初始化语法。您可以将其与任何结构一起使用。

Objective-C 的主要优点是它为您提供了一些非常类似于 Objective-C 的语法,其中字段接近值而不是通过定位隐含。(这并不是说这是故意相似,或者这是唯一的优势。但它很好。)

有时打字会稍微多一些,但我现在到处都在使用它。

考虑:

CGRect a = CGRectMake(a+c/2, b+d/2, c, d);

为了理解这一点,您需要了解参数的顺序。您还需要能够用眼睛轻松捕捉逗号。在这种情况下,这很容易,但如果表达式更复杂,您可能首先将它们存储在一个临时变量中。

C99方式:

CGRect a = (CGRect){
    .origin.x = a+c/2,
    .origin.y = b+d/2,
    .size.width = c,
    .size.height = d
};

它更长,但更明确。无论表达式有多长,也很容易遵循分配给什么的内容。它也更像是一种 Objective-C 方法。毕竟,如果 CGRect 是一个类,它可能看起来像这样:

CGRect *a = [[CGRect alloc] initWithOriginX:x originY:y width:w height:h];

您还可以执行以下操作:

CGRect a = (CGRect){
    .origin = myOrigin,
    .size = computedSize
};

在这里,您正在使用 aCGPoint和构建一个矩形CGSize。编译器理解.origin期望 aCGPoint.size期望 a CGSize。你已经提供了。都是肉汁。

等效代码是CGRectMake(myOrigin.x, myOrigin.y, size.width, size.height). 通过使用CGRectMake,您不再向编译器表达相同的含义。它不能阻止您将部分尺寸分配给原点。它也不会阻止您将宽度分配给高度。它甚至没有给你一个很好的线索来判断哪个是 X 和 Y。如果你使用过首先提供垂直坐标的 API,你会弄错的。

您也可以从结构中分配部分,也可以从浮动中分配部分:

CGRect a = (CGRect){
    .origin = myOrigin,
    .size.width = c,
    .size.height = d
};

CGRectMake功能早于 C99。我没有这方面的证据,但我认为如果 C99 先出现,CGRectMake可能根本就不存在;当您的语言无法直接执行初始化时,这是您编写的那种硬壳函数。但现在确实如此。

基本上,如果您使用它一段时间,您可能会更喜欢 C99 语法。它更明确、更灵活、更类似于 Objective-C 并且更难搞砸。

不幸的是,从 4.6 开始,Xcode 在 C99 字段初始值设定项列表中时不会自动完成结构字段名称。

于 2013-02-06T07:55:06.947 回答
4

这不仅是简写语法,而且在您只想更改大小而不更改原点时也很有用,CGRect反之亦然。

例如:我只想改变大小和位置有一个复杂的语法,我不想改变它。正常情况下,我会做

CGRect imageRect = CGRectMake(sprite.origin.x,sprite.origin.y,40, 60);

使用其他语法我会做

CGRect imageRect = (CGRect){.size = sprite.size};

我们也可以直接使用加法,减法和乘法,例如。

 CGRect imageRect = (CGRect){.size = ccpAdd(sprite.size,addsize)};

希望这可以帮助

于 2013-02-06T07:44:03.457 回答
0

它看起来像 C99 / GCC 样式初始化http://gcc.gnu.org/onlinedocs/gcc/Designated-Inits.html

于 2013-02-06T07:44:15.063 回答