As we have worked together over the last three years, some of the other iCodeBlog writers and I have gotten some pretty good coding conventions going that we thought would be good to share with you guys. One of the toughest to read coding conventions on iPhone is the declaration and synthesis of iVars. I’m going to go through a quick example of the correct way to do this, and the advantages of using the practice. So lets dive in.
Let’s make a simple class
Today we are going to make a simple class to represent a Blog Post. We will call this object a BlogPost and it will have a name, date and author. Let’s first take a look at the declaration of these variables.
This first snippet declares the three instance variables (iVars) that will make up our class. Convention is to have all instance variables declared with _ prefixes. Don’t worry, you will be able to access them without the _, but this is useful so developers know when they are accessing the synthesized getters and setters of an iVar as opposed to the iVar itself. We will see specifically what this means in a minute.
The other interesting convention here is declaring the Author class as an @class. What this does is tell the compiler that the class exists and should not produce a compile error. It does not go look at the Author class in any way however. You could declare this class like this and not even have an Author class in your project and the code would compile fine. The reason we do this is to avoid circular referencing. We will actually import the Author header in the main of this file. For more info on circular referencing check out the Circular Reference Wiki.
Synthesizing our iVars
Next we are going to synthesize these iVars to provide getters and setters for these objects.
This is the point in which we will make the iVars we have declared with _ available through another name, in this case we simply remove the _. This is accomplished by declaring the @property for each iVar with the name you would like to use when accessing these variables from a self. context. This means that you can get to the postName by using self.postName or _postName. postName will not work and self._postName will not work. The final piece of the puzzle is equating the @property declared variable with the actual declared iVar in your @synthesize declarations in your main. You can also see that here we have imported our Author.h class. This will ensure that even if Author has a reference to BlogPost, the references will not be circularly infinite.
Overriding a setter
The final thing I want to take a look at is what is would look like to override a setter method for one of these iVars. Let’s say we want a BlogPost to have a default name of “Blog Post Temp Name” if no name is provided. We can accomplish this by overriding the setter for postName. Here’s what that looks like.
The first thing we do here is declare the method. I like to have the variable passed into the setter be newPostTitle although you could leave it as postTitle because that name is only meaningful to the self. context. I personally find this to be a bit confusing to read so I usually add a “new” prefix to passed in variables in my overridden setters. With this done we strip the whitespace from the title and check if it is an empty string. If it is then we manually set the rawName to our default title.
With this done the final step is being memory safe in our assignment. We will be accessing the raw instance variable here through the _ prefix. This means we are going to be responsible for our own retaining. The process here goes, retain the new object, release your iVar object and then assign your iVar to the new object. This makes sure that memory is always handled correctly. If your current _blogPost and the passed in newBlogPost are different, it releases the old one retains the new one and we are all good. If they are the same exact object then we add a retain to newPostName to bring the retain count to 2 and then release _postName bringing the retain count back to 1. This is commonly done incorrectly in code I have seen and can introduce memory leaks.
That’s all for today guys. Happy iCoding!
Follow me @curffenach