Implementing accessor methods

By default, the compiler synthesizes accessor methods for any property you declare. Usually, accessor method implementations are straightforward and thus well-suited to being handed off to the compiler.

However, there are times where you will need an accessor to do something out of the ordinary. When this is the case, you can implement the accessor yourself in the implementation file.

There are two reasonable cases to implement an accessor yourself:

  • You need to update the app’s user interface when the change occurs.

  • You need to update some cached info when the change occurs.

For example, say you declared a property in a header file:

@​p​r​o​p​e​r​t​y​ ​(​n​o​n​a​t​o​m​i​c​,​ ​c​o​p​y​)​ ​N​S​S​t​r​i​n​g​*​ ​c​u​r​r​e​n​t​S​t​a​t​e​;​

When an object calls the setCurrentState: method, you want this method to do more than simply change the value of the property. In this case, you can explicitly implement the setter.

-​ ​(​v​o​i​d​)​s​e​t​C​u​r​r​e​n​t​S​t​a​t​e​:​(​N​S​S​t​r​i​n​g​ ​*​)​c​u​r​r​e​n​t​S​t​a​t​e​
{​
 ​ ​ ​ ​_​c​u​r​r​e​n​t​S​t​a​t​e​ ​=​ ​[​c​u​r​r​e​n​t​S​t​a​t​e​ ​c​o​p​y​]​;​

 ​ ​ ​ ​/​/​ ​S​o​m​e​ ​c​o​d​e​ ​t​h​a​t​ ​u​p​d​a​t​e​s​ ​U​I​
 ​ ​ ​ ​.​.​.​
}​

The compiler will see your implementation of setCurrentState: and will not create a setter for you. It will still create the getter method currentState.

If you declare a property and implement both accessors yourself, the compiler will not synthesize an instance variable.

If you still want an instance variable (and you usually do), you must create it yourself by adding an @synthesize statement to the class’s implementation.

#​i​m​p​o​r​t​ ​"​B​a​d​g​e​r​.​h​"​

@​i​n​t​e​r​f​a​c​e​ ​B​a​d​g​e​r​ ​:​ ​N​S​O​b​j​e​c​t​ ​(​)​
@​p​r​o​p​e​r​t​y​ ​(​n​o​n​a​t​o​m​i​c​)​ ​M​u​s​h​r​o​o​m​ ​*​m​u​s​h​r​o​o​m​;​
@​e​n​d​

@​i​m​p​l​e​m​e​n​t​a​t​i​o​n​ ​B​a​d​g​e​r​;​

@​s​y​n​t​h​e​s​i​z​e​ ​m​u​s​h​r​o​o​m​ ​=​ ​_​m​u​s​h​r​o​o​m​;​

-​ ​(​M​u​s​h​r​o​o​m​ ​*​)​m​u​s​h​r​o​o​m​
{​
 ​ ​ ​ ​r​e​t​u​r​n​ ​_​m​u​s​h​r​o​o​m​;​
}​

-​ ​(​v​o​i​d​)​s​e​t​M​u​s​h​r​o​o​m​:​(​M​u​s​h​r​o​o​m​ ​*​)​m​u​s​h​
{​
 ​ ​ ​ ​_​m​u​s​h​r​o​o​m​ ​=​ ​m​u​s​h​;​
}​

.​.​.​

The @synthesize statement tells the compiler that an instance variable named _mushroom is the backing variable for the mushroom and setMushroom: methods and that the instance variable should be created if it does not already exist.

If you left out the @synthesize statement in this case, the compiler would complain that _mushroom is undefined.

When you declare a readonly property, the compiler automatically synthesizes only a getter method and an instance variable. Thus, if you implement the getter method for a readonly property yourself, the effect is the same as implementing both accessors for a readwrite property. The compiler will not synthesize an instance variable, and you will need to synthesize it yourself.

You may be wondering, why declare a property at all in these cases? Declaring the property is still good shorthand for the accessor declarations and leads to visual consistency in your code.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset