Подтвердить что ты не робот

Синтаксис CGRect, который я не видел раньше

Я видел синтаксис ниже в некотором примере кода и не уверен, что понимаю его.

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

Это просто сокращенный способ инициализации эквивалента CGRect:

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

Есть ли какая-либо польза от этого синтаксиса, кроме немного меньшего набора текста?

4b9b3361

Ответ 1

Этот синтаксис инициализации 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
};

Здесь вы создаете прямоугольник с помощью CGPoint и CGSize. Компилятор понимает, что .origin ожидает CGPoint, а .size ожидает 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.

Ответ 2

Это не просто сокращенный синтаксис, но также полезен, когда вы хотите изменить только размер, а не начало в 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)};

Надеюсь, что это поможет