{"id":23,"date":"2009-01-01T04:42:32","date_gmt":"2009-01-01T08:42:32","guid":{"rendered":"http:\/\/adamrosenfield.com\/blog\/?p=23"},"modified":"2011-02-20T23:23:46","modified_gmt":"2011-02-21T03:23:46","slug":"beware-of-struct-properties","status":"publish","type":"post","link":"http:\/\/adamrosenfield.com\/blog\/2009\/01\/01\/beware-of-struct-properties\/","title":{"rendered":"Beware of struct properties"},"content":{"rendered":"<p><a href=\"http:\/\/developer.apple.com\/documentation\/Cocoa\/Conceptual\/ObjectiveC\/Introduction\/chapter_1_section_1.html\">Objective-C<\/a> is an interesting programming language.  Unlike C++, it&#8217;s a <em>strict<\/em> superset of C \u2014 every valid C program is a valid Objective-C program.  While most C programs are valid C++ programs, there are <a href=\"http:\/\/en.wikipedia.org\/wiki\/Compatibility_of_C_and_C%2B%2B\">certain incompatibilities<\/a> such as the introduction of new keywords that make the relationship not strict.<\/p>\n<p>One of the many features that Objective-C brings is <em>properties<\/em>.  Properties essentially act like public member variables, but whenever you get or set them, those gets and sets get rerouted through a function call (more specifically, the passing of a message in Objective-C parlance).  For example, if <code>value<\/code> is a property of whatever class <code>my_object<\/code> belongs to, then the code<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">int x = my_object.value;<\/pre>\n<p>gets converted into<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">int x = &#x5B;my_object value];  \/\/ pass the 'value' message to my_object<\/pre>\n<p>And this code<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">my_object.value = 3;<\/pre>\n<p>gets converted into<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\/\/ pass the 'setValue' message with parameter 3 to my_object\r\n&#x5B;my_object setValue:3];<\/pre>\n<p>Getters and setters allow you to do things like parameter validation, logging, or anything else you want whenever a property is read from or written to.  The dot notation is just <a href=\"http:\/\/en.wikipedia.org\/wiki\/Syntactic_sugar\">syntactic sugar<\/a>.<\/p>\n<p>Now suppose that <code>value<\/code> isn&#8217;t a simple integer, but rather a struct of some sort, such as a <code>CGPoint<\/code>.  A <code>CGPoint<\/code> is a standard 2D point class, containing two float members named <code>x<\/code> and <code>y<\/code>.  Consider the following innocent-looking code:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">my_object.value.x = 3;  \/\/ set x-coordinate to 3?<\/pre>\n<p>If <code>value<\/code> were just a plain ordinary struct member, this would do exactly what you&#8217;d expect &#8211; set the x-coordinate to 3, and leave the y-coordinate untouched.  But as you&#8217;ve probably surmised by now, that&#8217;s not what happens when <code>value<\/code> is a property.  Why not?  Well, since we&#8217;re not assigning to it, it gets turned into this:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">&#x5B;my_object value].x = 3;<\/pre>\n<p>And <code>[my_object value]<\/code> returns an object of type <code>CGPoint<\/code>.  And structs are returned&#8230;..by value.  Thus, we&#8217;re assigning 3 to the x-coordinate of a temporary <code>CGPoint<\/code> which is a copy of our object&#8217;s <code>value<\/code> property.  The only proper way to resolve this is to make <code>value<\/code> a regular class member and not a property, reassign a completely new <code>CGPoint<\/code> to <code>value<\/code>, or add messages that allow you to independently set the x- and y-coordinates.  Depending on whether or not you own the code for the class, this may or not be possible.<\/p>\n<p>Fortunately, in the case of <code>CGPoint<\/code>s, it&#8217;s relatively easy to assign a new value with <a href=\"http:\/\/developer.apple.com\/documentation\/graphicsimaging\/reference\/CGGeometry\/Reference\/reference.html#\/\/apple_ref\/c\/func\/CGPointMake\"><tt>CGPointMake()<\/tt><\/a>:<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">my_object.value = CGPointMake(3, my_object.value.y);<\/pre>\n<p>But for more complicated structs, this solution could be less than ideal.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Objective-C is an interesting programming language. Unlike C++, it&#8217;s a strict superset of C \u2014 every valid C program is a valid Objective-C program. While most C programs are valid C++ programs, there are certain incompatibilities such as the introduction of new keywords that make the relationship not strict. One of the many features that [&hellip;]<\/p>\n","protected":false},"author":2,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5],"tags":[],"class_list":["post-23","post","type-post","status-publish","format-standard","hentry","category-programming"],"_links":{"self":[{"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/posts\/23","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/comments?post=23"}],"version-history":[{"count":3,"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/posts\/23\/revisions"}],"predecessor-version":[{"id":28,"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/posts\/23\/revisions\/28"}],"wp:attachment":[{"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/media?parent=23"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/categories?post=23"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/adamrosenfield.com\/blog\/wp-json\/wp\/v2\/tags?post=23"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}