В приложении для пианино я задаю координаты черных клавиш. Вот строка кода, вызывающая ошибку.
'blackKey' и 'whiteKey' являются customViews
blackKey.center.x = (whiteKey.frame.origin.x + whiteKey.frame.size.width);
В приложении для пианино я задаю координаты черных клавиш. Вот строка кода, вызывающая ошибку.
'blackKey' и 'whiteKey' являются customViews
blackKey.center.x = (whiteKey.frame.origin.x + whiteKey.frame.size.width);
Другие ответы точно не объясняют, что здесь происходит, так что это основная проблема:
Когда вы пишете blackKey.center.x
, blackKey.center
и center.x
выглядят как доступ к членам структуры, но на самом деле это совершенно разные вещи. blackKey.center
— это доступ к свойству, который приводит к чему-то вроде [blackKey center]
, который, в свою очередь, к чему-то вроде objc_msgSend(blackKey, @selector(center))
. Вы не можете изменить возвращаемое значение функции, например objc_msgSend(blackKey, @selector(center)).x = 2
— оно просто не имеет смысла, потому что возвращаемое значение хранится где-либо значимо.
Поэтому, если вы хотите изменить структуру, вам нужно сохранить возвращаемое значение свойства в переменной, изменить переменную, а затем установить для свойства новое значение.
anObject.anNonStructProperty.anProperty = someValue
правильно? Как вы говорите, что мы не можем изменить возвращаемое значение функции. Не могли бы вы объяснить?
- person EmptyStack; 16.08.2011
anObject.someProperty = something
, это не эквивалентно [anObject someProperty] = something
— вместо этого оно эквивалентно [anObject setSomeProperty:something]
. Вы отправляете сообщение объекту для вызова метода установки. Вы не присваиваете возвращаемое значение метода. Внешний вид присваивания — это просто синтаксический сахар, точно так же, как внешний вид доступа к члену — это синтаксический сахар для метода-получателя.
- person Chuck; 16.08.2011
blackKey.center
внутренне вызывает objc_msgSend(blackKey, @selector(setCenter:))
, а не objc_msgSend(blackKey, @selector(center))
, верно?
- person Adithya; 22.07.2014
blackKey.center
звонит setCenter:
, то как вы себе представляете аргумент? [blackKey setCenter: ?????]
. Это просто [blackKey center]
.
- person Chuck; 22.07.2014
Вы не можете напрямую изменить значение x
для CGPoint
(или любое значение структуры) таким образом, если оно является свойством объекта. Сделайте что-то вроде следующего.
CGPoint _center = blackKey.center;
_center.x = (whiteKey.frame.origin.x + whiteKey.frame.size.width);
blackKey.center = _center;
blackKey.center = CGPointMake ( whiteKey.frame.origin.x + whiteKey.frame.size.width, blackKey.center.y);
Один из способов сделать это.
Один из вариантов использования макросов:
#define CGPOINT_SETX(point, x_value) { \
CGPoint tempPoint = point; \
tempPoint.x = (x_value); \
point = tempPoint; \
}
#define CGPOINT_SETY(point, y_value) { \
CGPoint tempPoint = point; \
tempPoint.y = (y_value); \
point = tempPoint; \
}
CGPOINT_SETX(blackKey.center, whiteKey.frame.origin.x + whiteKey.frame.size.width);
или немного проще:
CGPOINT_SETX(blackKey.center, CGRectGetMaxX(whiteKey.frame));
do ... while(0)
? Разве области блока { ... }
недостаточно, чтобы объявить временные переменные (без потенциального столкновения имен с чем-то снаружи) и чтобы операторы внутри выполнялись ровно один раз?
- person Nicolas Miari; 09.09.2015
do ... while(0)
так долго, что не осознавал, что блоки {...}
работают нормально. Спасибо. Упрощение.
- person ThomasW; 09.09.2015
do ... while(0)
здесь: stackoverflow.com/questions/154136/ В моем случае это не обязательно, но есть случаи, когда это необходимо.
- person ThomasW; 09.09.2015
Как его значения, вы не можете присвоить значение выражению. Например, a + b = c запрещено.
whiteKey.frame.origin.x + whiteKey.frame.size.width
совпадает сCGRectGetMaxX(whiteKey.frame)
. - person ThomasW   schedule 09.09.2015