Proper way to use instance variables/property/synthetize with ARC

Ondrej Skalicka picture Ondrej Skalicka · Mar 13, 2013 · Viewed 7.1k times · Source

What is the proper way to work with instance variables (declared on interface), their @property and @synthesize, when working in ARC project? What I now do is following:

SomeClass.h:

@interface SomeClass : NSObject {
  NSString *someString;
}
@property(nonatomic, copy) NSString* someString;

and SomeClass.m:

@implementation SomeClass

@synthesize someString;

- (void)someMethod {
  self.someString = @"Foobar";
}

The thing is that there are other approaches that works, like using just the @property:

SomeClass.h:

@interface SomeClass : NSObject
@property(nonatomic, copy) NSString* someString;

Accessing the someString without self:

SomeClass.m:

@implementation SomeClass

@synthesize someString;

- (void)someMethod {
  someString = @"Foobar";
}

etc. I'm new to Objective-c, I'm used to Java. What is the proper way to work with attributes then? I understand that special cases will have special behavior, but what is the best approach in general? (by general I mean I want to access the variable from the class itself and from "outside" and I want ARC to still work correctly, eg. I don't have to worry about memory leaks)

Answer

Mike Weller picture Mike Weller · Mar 13, 2013

For simple properties, you don't need the instance variable declaration or the @synthesize. The clang compiler will generate both for you by default. So you could write this in the header:

@interface SomeClass : NSObject

@property (nonatomic, copy) NSString *someString;

@end

And the implementation:

@implementation SomeClass

- (void)someMethod {
    self.someString = @"Foobar";
}

@end

Avoid direct instance variable access unless you are in the -init method or overriding the setter. Everywhere else you should use the dot syntax (self.someString). If you do need access to the instance variable, the default synthesize will create an underscore-prefixed ivar, e.g. _someString.

Note that for classes with mutable versions like NSString/NSMutableString and NSArray/NSMutableArray the standard practice is to use a copy property. If you use strong on a string or array, the caller might pass in a mutable version and then mutate it from under you, causing hard-to-find bugs.