I’m reading a book about iOS (it calls Programming iOS 4, by Matt Neuburg) and in the paragraph where he explains properties he said these words:
Objective-C uses dot-notation for properties, and C uses dot-notation for structs; these can be chained. So, for example, UIView’s frame is a property whose value is a struct (a CGRect); thus, you can say myView.frame.size.height, where frame is a property that returns a struct, size is a component of that struct, and height is a component of that struct. But a struct is not a pointer, so you cannot (for example) set a frame’s height directly through a chain starting with the UIView, like this:
myView.frame.size.height = 36.0; // compile error
Instead, if you want to change a component of a struct property, you
must fetch the property value into a struct variable, change the
struct variable’s value, and set the entire property value from the
struct variable:
CGRect f = myView.frame;
f.size.height = 0;
myView.frame = f;
I don’t understand well, why I can’t use the line below?
myView.frame.size.height = 36.0;
Background
A variable in a programming language is a box which has a name (sometimes termed a “reference” or a “pointer’ depending on the language). This box contains a value of some type. Values don’t change, the contents of boxes do. E.g in the following code:
The second line doesn’t change
4, it changes what is in boxa.Types in programming languages fall into two categories: value types and reference types.
For value types what gets passed around and stored in boxes is a representation of the actual value, e.g. in the code:
The function
sqrtis not passedabut the value that is stored ina– which is some sequence of bits which represent the number 9.0; what is returned bysqrtis some sequence of bits which represent 3.0, and these are stored intob. The bits that are passed around, you use your words in one of your comments, are the “real value”.For reference types what gets passed around and stored in boxes is some representation of the name of the box (chunk of memory) which contains the actual value. In Objective-C reference types are distinguished by using
*in their declaration (other languages don’t require a*, e.g. Java & C# – they know which types are reference types based on their kind). E.g in the code:the method call doesn’t return a window value itself but the name of a box containing the window value. Again to use your words, the “real value” is never passed around rather the name of a box containing that value is passed around.
Traditionally “small” types were represented by value types – integers, floating point numbers, characters, etc.; while “large” values by reference types. However each programming languages makes its own choices – some are even defined to only operate with reference types.
Answer
In your example
myView.frameis a property, and a property is implemented using a method. In Objective-C (and C, C++) astructtype is a value type – it is treated just like integers and floating point numbers, it’s value is passed around and stored in boxes. So what is returned by the property is, using your words, the “real struct” – it’s as “real” as the bits representing 3.0 in the above example.What isn’t being returned is the name of the box containing a struct value, and without access to a box you can’t change its contents. Which is why
myView.frame.size.height = 36.0;is incorrect – you’re trying to change part of a value, and values don’t change.However given an
NSRectbox you can change part of its contents. E.g. in the code:The
.size.heightis identifying which part of the boxaRectto change, and the representation of36.0is stored into that part of the box.HTH