2016-07-17 7 views
0

Я выполняю это упражнение в книге, и в какой-то момент есть реализация для метода, который создает метки, помещенные случайным образом в представление. Вот код:Две строки кода, которые говорят то же самое?

1 - (void)drawHypnoticMessage:(NSString *)message{ 
2  for(int i =0; i<20; i++){ 
3   UILabel *messageLabel = [[UILabel alloc] init]; 

4   messageLabel.backgroundColor = [UIColor clearColor]; 
5   messageLabel.textColor = [UIColor whiteColor]; 
6   messageLabel.text = message; 
7   [messageLabel sizeToFit]; 

8   int width = self.view.bounds.size.width - messageLabel.bounds.size.width; 
9   int randomX = arc4random() % width; 
10   int height = self.view.bounds.size.height - messageLabel.bounds.size.height; 
11   int randomY = arc4random() % height; 

12   CGRect frame = messageLabel.frame; 
13   frame.origin = CGPointMake(randomX, randomY); 
14   messageLabel.frame = frame; 

15   [self.view addSubview:messageLabel]; 
16  } 
17 } 

Это работает нормально. Мой вопрос касается линии 12 и 14. Когда я переписывал это упражнение в Xcode из книги, и я достиг линии 12, я инстинктивно изменил его:

12 CGRect frame; 

Это не сработало, и я не» понять почему. Для меня строки 12 и 14:

12 CGRect frame = messageLabel.frame; 

14 messageLabel.frame = frame; 

Говорят то же самое дважды, конечно. Может кто-нибудь объяснить, почему это не так?

+0

Я думаю, что вы должны понимать, что = означает назначение в этом контексте. Он не представляет собой равенство (как в случае с IF на некоторых языках). Следовательно, A = B не означает то же самое, что и B = A, а строка 13 настраивает внутреннее значение перед повторным назначением кадра –

ответ

3

Objective-C перегружает оператор доступа к элементам структуры C (.) Для доступа к свойствам объектов Objective-C. Проблема в том, что вы не можете смешивать два в одном присваивании, потому что парсер компилятора запутывается.

messageLabel - объект, который имеет свойство под названием frame. frame - это структура с двумя членами: origin и size.

Чтобы обойти это ограничение, необходимо использовать временную переменную для хранения-структуру (например, frame), манипулировать этой копии (Структуры копируются на присвоение), а затем назначить новую-структуру (frame) в собственность, который обновляет значение свойства.

2

Вы изменяете рамку в строке 13, то есть изменяете исходное значение. Книга показывает вам общую методику изменения фрейма, поскольку вы не можете самостоятельно изменить значение точки или размера.

+0

Извините, но я этого не понимаю. Вы говорите, что, изменяя происхождение кадра (в строке 13), каким-то образом кадр перестает быть = messageLabel.frame ?? – Paul

+1

Да, вы создаете новый «кадр», который имеет значение фрейма messageLabel, а затем вы изменяете этот новый «кадр» и отображаете это сообщение в сообщении, а ваш кадр MessageLabel присваивает этому новому кадру. Вы можете добиться того же с помощью этой строки кода, «messageLabel.frame = CGRectMake (randomX, randomY, messageLabel.frame.size.width, messageLabel.frame.size.height); – JingJingTao