Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why is "expression not assignable" (UIView.frame.origin)?

This question is not a "how do I" but rather a "why is this" concerning some Class properties in Objective-C.

I understand that the two examples below are not allowed and result in an error ("expression not assignable"):

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

and that the proper way to do this is to create a new CGRect, set the values desired and then assign it:

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

I'd like to understand why this is.

CGRect is a struct containing two structs. Does the restriction have to do with how structs are allocated, to prevent an assignment which might overflow that memory? Or is it more of a convention concerning public and private properties?

I realize this seems like a minor/basic question but I think it is important to clear up muddy/bad understandings of these fundamental sort of things.

like image 813
spring Avatar asked Aug 26 '12 18:08

spring


2 Answers

It's because if you were able to directly change a frame's origin or size, you would bypass the setter method of UIView's frame property. This would be bad for multiple reasons.

UIView would have no chance to be notified about changes to it's frame. But it has to know about these changes to be able to update it's subviews or redraw itself.

Also, for KVO to work, you have to use the correct setters (either by using setFrame: or the dot notation).

like image 175
DrummerB Avatar answered Oct 04 '22 11:10

DrummerB


The problem with assigning elements of the struct is that the class owning the struct will have no idea the struct has been changed. This is not good when you talk about, say, the origin of a frame: UIView is expected to move in response to changing the origin, but since the class would not be notified of the change, no moving would occur.

Setting the frame, on the other hand, can be detected, because UIView's setFrame method would be invoked. This is the code in which UIView could take care of resizing, repositioning, and so on.

like image 32
Sergey Kalinichenko Avatar answered Oct 04 '22 12:10

Sergey Kalinichenko