Coding Style with Properties


#1

As I’m learning Objective-C and iOS programming, I’m struggling with the best coding style to use with properties. I really like BNR’s style of avoiding Dot Syntax, but I noticed that I need to be careful if the name of the instance variable matches the property name.

Let’s say I have the following:

If I set the text with [[self someText] setText:@"type here"]
Then I’m accessing the instance variable through the property. If I set the text with [someText setText:@"type here"]
Then I’m accessing the instance variable directly.

I’m worried that I could open myself up to problems by using code where it’s not clear if I’m using the property or the instance variable. I understand that in pre-ARC days there was a similar problem if you used dot notation and mixed up self.someText and someText. Is that true? Is there a better way to handle properties and instance variables? Is [self varName] really required every time you access an object’s internal variables?

Sorry if the question is vague. I’m just trying to figure out the best practice to use going forward. Thanks!

P.S. I have tried naming my instance variables “someText_” and leaving the property “someText”. It’s very clear which one I’m accessing in the code. The downside is that is kind of ugly and requires more typing.


#2

This is definitely something that poses a problem. However, you can work with @synthesize to alleviate some of the concerns. For example say you have a property declaration like so:

When you synthesize your property in the .m file you can do something like this:

This synthesizes the firstName property (provides a getter and setter) and creates a backing instance variable called _firstName;

Unless I’m working in a custom setter or getter, I find it best to access my instance variables via:

Doing so allows you to work with Key-Value Observing (KVO) to observe when your property values are changed, either by the class with the property or another class who modifies the property.

A class’s methods have access to the instance variables of the class by name. In the above example, any of the methods of this class can access _firstName by using _firstName. Aside from custom accessors, what is the motivation for using instance variables directly? If you want to use a property because of the memory management it gives you with regards to instance variables AND use the property privately in your methods, a private class extension might be a better place to declare the property.

Also, you can choose to use properties in your -init method or you can simply assign to the backing instance variable as ARC considers an assignment to be a strong reference.

It is also worth noting that instance variables and properties are not the same thing. Properties may in fact be backed by instance variables but it is not required. Some properties like a fullName property may be derived from a firstName and lastName property so there is not backing instance variable.


#3

I just want to be consistent. I don’t really want a mix of ivar accesses and properties accesses or a mix of using the set message, but not using the get message. Since I know I’ll have uses for properties, that’s the direction I’ve been taking. I think some of the confusion is just due to so many examples using dot notation (plus past C/C# experience) and not knowing how to do it “the Objective-C way”. :slight_smile:


#4

There’s a lot of differing opinions on this topic, here is my opinion:

If you are accessing a superclass’s instance variable in any way, you should always use the accessor methods.
If you are getting your own class’s instance variable, I typically just access it directly.
If you are setting your own class’s instance variable, I typically use the setter method unless I’m intentionally avoiding the additional behavior of a setter (which doesn’t happen often).

Obviously, if you do not have a backing instance variable, you must use the accessors. And if you don’t have a property, you must use direct access.

One other opinion related to this topic: you don’t need a property for every instance variable. I sometimes see programmers just declare everything as a property. You only want a property if one of the following are true:

  1. You want other classes to be able to access that instance variable thru the setter/getter method.
  2. You have extra work to do in your setter/getter method other than just assigning the ivar.

Additionally, on 2, you should be careful not to expose a property to other classes unless you intend to. If you want the setter/getter for the extra behavior, but don’t want other classes to see it, declare it in a class extension in the .m file:


@interface MyClass ()
@property int foo;
@end
@implementation MyClass
@synthesize foo;
- (void)setFoo:(int)a
{
    foo = a + 1;
}
@end

#5

Thanks for the advice! I think I was over-thinking things before.