Почему "выражение не назначается" (UIView.frame.origin)?

Этот вопрос не является "как я", а скорее "почему это" относительно некоторых свойств класса в Objective-C.

Я понимаю, что два приведенных ниже примера не допускаются и приводят к ошибке ( "выражение не назначается" ):

self.myUIView.frame.origin.x = 50;
self.myUIView.frame.origin = CGPointMake(50,50);

и что правильный способ сделать это - создать новый CGRect, установить нужные значения и затем назначить его:

CGRect rect = self.myUIView.frame;
rect.origin = CGPointMake(50, 50);
self.myUIView.frame = rect;

Я хотел бы понять, почему это так.

CGRect - это структура, содержащая две структуры. Связано ли ограничение с тем, как распределяются структуры, чтобы предотвратить присвоение, которое может переполнить эту память? Или это скорее соглашение о публичной и частной собственности?

Я понимаю, что это похоже на второстепенный/основной вопрос, но я думаю, что важно очистить грязное/плохое понимание этих фундаментальных вещей.

Ответ 1

Это потому, что если вы смогли напрямую изменить начало или размер кадра, вы обойдете метод setter свойства рамки UIView. Это было бы плохо по нескольким причинам.

У UIView не будет возможности получать уведомления об изменениях в нем. Но он должен знать об этих изменениях, чтобы иметь возможность обновлять его в режиме просмотра или перерисовывать.

Кроме того, для работы KVO вам нужно использовать правильные сеттеры (либо с помощью setFrame: либо с помощью точечной нотации).

Ответ 2

Проблема с назначением элементов struct заключается в том, что класс, владеющий struct, не имеет понятия, что struct был изменен. Это плохо, когда вы говорите, например, о происхождении фрейма: UIView, как ожидается, будет двигаться в ответ на изменение начала, но поскольку класс не будет уведомлен об изменении, никакого перемещения не произойдет.

Настройка frame, с другой стороны, может быть обнаружена, потому что будет вызван метод UIView setFrame. Это код, в котором UIView может позаботиться о изменении размера, изменении местоположения и т.д.