1

What does the following expression means in Swift:

 [wordmarkFrameAnimation addKeyFrames:@[
     ({
         IFTTTAnimationKeyFrame *keyFrame = [IFTTTAnimationKeyFrame keyFrameWithTime:timeForPage(1) andFrame:CGRectOffset(self.wordmark.frame, 200, 0)];
         keyFrame.easingFunction = IFTTTEasingFunctionEaseInQuart;
         keyFrame;
     }),
 ]];

I know that the outer part is an array (@[...]) but what does the part beginning with ({ and ending with }) means?

  • I dont understand the question – Jeef Jun 01 '15 at 18:06
  • It's a round-about way in Obj-C to create an array from an expression, where the expression is derived from the scoped block `{...}`. The last statement of the scope: `keyFrame` forms the value of the expression (though I haven't used or tested this). If you wanted to use a similar form in Swift, you could (I think) replace `({...})` with the execution of an inlined closure, with the form: '{... keyFrame stuff in here... }()' – Chris Conover Jun 01 '15 at 18:10
  • Compare (for example) [iOS Name of this way of building and returning an object in Objective-C](http://stackoverflow.com/questions/21909511/ios-name-of-this-way-of-building-and-returning-an-object-in-objective-c). – Martin R Jun 01 '15 at 18:14

1 Answers1

3

Unlike Swift, Objective-C - because it is C - can create a local scope anywhere with simple curly braces. Moreover, by a GCC extension to the C language, this scope can be used to generate a value — namely, the last expression in the curly braces — when the curly braces are themselves surrounded by parentheses. Thus, this is a way of defining, configuring, and returning keyFrame inline.

So, to understand in Swift terms what it means, consider it as roughly equivalent to this sort of thing, which is actually a fairly common Swift idiom (I call it define-and-call):

let arr : [UIView] = [
    {
        let v = UIView(frame:CGRectMake(0,0,100,100))
        v.opaque = true
        v.backgroundColor = UIColor.redColor()
        return v
    }()
]
matt
  • 515,959
  • 87
  • 875
  • 1,141
  • 2
    It's a feature of GCC (also supported by clang) called "statement expressions". Both the parentheses and braces are required. http://gcc.gnu.org/onlinedocs/gcc/Statement-Exprs.html – mipadi Jun 01 '15 at 18:09
  • @mipadi Correct-a-mundo. I didn't want to get into the nitty-gritty. :) Maybe I should modify to say "simple curly braces in parentheses". – matt Jun 01 '15 at 18:10
  • 1
    Local scope `{ ... }` and statement expression `({ ... })` are not the same. The former does *not* have a value (as far as I know). – *"in Objective-C, every statement has a value"* I am not sure if this is correct. – Martin R Jun 01 '15 at 18:16
  • 2
    I have no idea what you mean, but `;` , `{ ; }`, `{ 12; }`, `if (1 < 2) { }` are all valid (Objective-)C statements, but not *expressions*. None of them has a value. – Martin R Jun 01 '15 at 19:01
  • 2
    @matt It is not correct. Statement expressions are expressions, not statements. (This is why they are called that way.) There are expression statements, too, but they do not have a value, because they are statements, not expressions. So: In C and Objective-C a statement never has a value. (Or the other way round: Something that has a value, is always an expression.) – Amin Negm-Awad Jun 01 '15 at 19:07
  • 1
    @MartinR Even `12;` has no value. Of course, the *contained expression* `12` has a value, but the statement (`12;`) has no value. There is no statement in C or Objective-C having a value. – Amin Negm-Awad Jun 01 '15 at 19:13