Touch Code Magazine

Posts about Swift, Apple, iOS, conferences, and more

CGPointMake, CGSizeMake, etc. shortcuts

I don’t come from a C background (when it was the time to choose I went with Pascal – it was pretty hot at the time), so some C style stuff in Objective-C are kind of mysterious to me – and I guess also for many of you.

One of those oldies are the structures. Unfortunately they are all over the place – CGPoint, CGSize and CGRect for example. And it always annoys me to have all these long function names to write like CGPointMake, CGSizeMake and CGRectMake. While digging through some 3rd party libraries I noticed something that looks like the ultimate solution for me and my functions hurdle.

In C you can have something called – structure initializer – pretty awesome thing. Let’s have a look how you can create a CGPoint using an initializer:

Pretty short and cool too!

You can also give it a try to see that the point is exactly set as you wanted:

Awesome! Let’s have a look at a CGSize initializer:

Alright! Great stuff! How about a CGRect though? It’s a structure made out of other structures – a CGPoint and a CGSize… Hmmm … Let’s just give it a try:

Wow. How that works? All the values are just fed into the structure’s components one after another…

So … it doesn’t work only for the ones we already had a look at, but also for all kind of structures – you just need to know the exact order the variables inside the structure are defined in and just feed values in.

You can also dynamically cast these if you need to, like so:

That’s pretty much all about the structure initializers, I love them and hopefully they help you out too.

Tagged under: , , , , , , , , , , ,

Pin it

Marin Todorov is an independent iOS consultant and publisher with complimentary background in server and desktop development. He started developing on an Apple ][ more than 20 years ago and keeps rocking till today. Meanwhile he has worked in great companies like Monster Technologies and Native Instruments, has lived in 4 different countries, and (more recently) is one the founding memebers of the raywenderlich.com tutorial team. Besides crafting code, Marin also enjoys bloging, writing books, teaching and training others, and speaking at mobile conferences. He sometimes open sources his code. He walked the way to Santiago.

Website: http://www.touch-code-magazine.com

6 Comments

  1. jo

    i don’t think this is a good idea.
    if apple changes anything in the CGPoint structure all code will become unusable. better use a #define for CGPointMake like in cocos2d for example.

  2. I

    It’s extremely unlikely that Apple would ever change basic structs like these. It would break binary compatibility for all existing apps and libraries. And what would they even change? Swap the x and y fields? Add a z field? Swapping doesn’t make any sense and if they wanted a 3D point, they would just make a new struct. A change in data type (float -> double) wouldn’t break the C99-style initializers as the ordering is the same, and this actually already happens when building for a 64-bit Mac.

    These structs are fundamental enough that you can expect them to never change in a source-incompatible way.

  3. Karl

    I suppose the other problem is use. For example, CGRectMake is not the only CGRect macro. There’s -Zero -IsEmpty, IsNull, and all the -Get…’s. To be consistent in your code, it would seem better to use the macro..

  4. Kevin

    There is still the issue of readability. In classic C form, the function as used in code is just a list of unnamed parameters:

    CGRect rect = CGRectMake(10.f, 20.f, 480.f, 360.f);

    Now I know what each of those represent from seeing that function a zillion times, but compared to the natural language readability of Objective C, it’s pretty obscure looking. The above style of struct initialization isn’t much better, though at least it breaks up the origin and size:

    CGRect rect = {{10.f, 20.f}, {480.f, 360.f}};

    These eliminate a function call as well! While that is quite a micro-optimization for normal code, it has some useful consequences. For example, you can now declare these as compile-time constants. But what about readability? C99 to the rescue!

    CGRect rect = (CGRect){
    .origin = (CGPoint){
    .x = 10.f,
    .y = 20.f,
    },
    .size = (CGSize){
    .width = 480.f,
    .height = 360.f,
    }
    };

    or, shortening things up a bit:

    CGRect rect = (CGRect){
    .origin.x = 10.f,
    .origin.y = 20.f,
    .size.width = 480.f,
    .size.height = 360.f,
    };

    I especially like that notation for compile-time constants, as it’s easy to read and not getting in the way of the flow of code (where the multiple-line approach may be a nuisance). Also all these struct initializer methods make it easy to reuse a CGPoint or CGSize for multiple CGRect structs – just set .origin or .size!

  5. Matt

    You could argue that they are not a list of unnamed parameters as they would be constants or variables, with meaningful names. Readability is severely reduced by arbitrary constants.

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">

Back to top