What happens, however, when you want a property to be read-only to other objects, but you also want to be able to use the synthesized mutator within your own class to assign new values? In other words, what do you do when you want a property to be read-only to the rest of the world, but read/write within your own class?
Extensions to the rescue. Before we had extensions, it was common to declare a category at the top of your implementation file with any private methods. This would prevent the compiler from complaining when you called a private method from within your class. The compiler would see the private method declaration in the implementation file when your class was compiled, but wouldn't see those methods when it compiled other classes. Under this old way of doing it, we would simply include the mutator method in the category, and only put the accessor in the header file, and that would effectively make the instance value read-only to the rest of the world by not exposing the mutator.
In Objective-C 2.0, this practice has been formalized into extensions, which are basically just anonymous, nameless categories. One thing you can do with an extensions is to redefine your declared properties. So, you can declare a property in your header file as readonly, and then in your implementation file, create a class extension with the same properties re-declared as readwrite. Ét voilà! Your class will be able to use both the accessor and mutator for those properties while external classes will only be able to use the accessor. Cake and nom nom. Life is good.
Note: you cannot change all aspects of a property. You can't, for example, declare it copy in your header file and retain in your extension.Let's look at a simple example. Let's say we were writing a subclass of NSOperation that had two properties. We want these values to be set by in the init call, but because our operation will be running concurrently on another thread, we don't want the values changed after that by external objects, but we may need to change them ourselves. To do that, we might declare our class like this:
And then, in the implementation file, we would use an extension to redefine those two properties:
It's a simple trick, but one with the potential to make your life more pleasant.