So I have been seriously coding Objective-C for about a year now. I have spent a lot of time just sort of typing things only having a surface knowledge of what I was coding and why.
One thing I noticed in my independent iOS studies is that there are a lot of different places to create variables. Also, there are variables and there are properties.
Why pick a property over a variable? Why declare the property in the header file instead of the implementation file?
If you are coming from a language like Java, you will know that you are required to write getters and setters for all of your properties. Back in the olden days of Objective-C, you used to have to do this as well. A few years ago Apple decided to introduce a @synthsize property to do the getting and setting for you. Then a few years ago they decided that since it was best practice to do that anyway, it is all baked into the code for you. Just because you aren’t doing it and you don’t see it doesn’t mean it isn’t happening under the hood.
Properties are backed by instance variables. So, if you declare a property in the implementation part of your .m file, a backing ivar is created.
So, if you have:
@property (copy, nonatomic) NSString *myString;
you will then be able to access it in your methods by using:
_myString = @“Hello, World!”;
In this instance _myString is an ivar of the property *myString.
Header Vs Implementation
One thing I wondered about a lot while working with tutorials is why you would choose to place things in the header file over the implementation file. Back when I was just typing until something worked I put everything in the Header files because they would show up in the autocomplete. Then I started seeing tutorials where they declared properties in the implementation file and used ivars.
If you want a property to be accessible by another class, you need to set the property in the header file. You don’t always need or want a property to be accessible to another class because it is something you are using internally. In those cases, use either a property or an ivar in the implementation file.
Apple’s best practices say to always use a property for data encapsulation. There is some debate about whether to use them or not, but that goes beyond the scope of what I am going to talk about here.
There is a wonderful blog post from the Big Nerd Ranch discussing this issue. In this post I am simply exploring what the scope of everything is, so if you are interested, then check it out.
Instance Variables (or Ivars) are created in the @interface of your .m file. They are immediately differentiated by the fact that their declaration begins with their type and not with @property.
It is a coding convention to begin Ivars with an underscore. When you create properties that are backed by instance variables those will always start with an underscore, so it keeps things consistent in your program to start yours with an underscore as well.
I created a small demo project on GitHub to just generally show better examples of this code in action.
This is intended to be a gentle introduction to the scope of various properties and variables. I want to explore some of this topic further, such as what the strong, non-atomic, copy, retain all mean and why you use those, but that is a large enough topic for its own blog post.
If you have any suggestions about Objective-C minutiae you would like clarified and explored, drop me a line on either Twitter or App.net at @RedQueenCoder. Happy to take suggestions!
I hope this clarifies for you how to choose where you set your properties, or at least answers your questions about why they are set in so many different places.