Proper way to use instance variables/property/synthetize with ARC [duplicate]
Asked Answered
D

2

6

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)

Dogooder answered 13/3, 2013 at 11:46 Comment(3)
Just define properties. And if you are using Xcode 4.5+ , you dont even need the synthesize statement. That is considered as the proper way, because properties will automatically create iVars. If you need to use an iVar, then if in Xcode 4.5+, use "_" before the name of the property(as they are created automatically), if not, then create them like this: @synthesize variable = _variable;Harlequin
@pe60t0 The need to no longer use the @synthesize statement was actually introduced with Xcode 4.4.Refined
My bad, cannot edit the comment now.Harlequin
C
9

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.

Clasping answered 13/3, 2013 at 12:22 Comment(0)
M
-2

Check out this SO post for information about ARC.

(Edited) The "strong" attribute tells ARC to keep an object around until the object with the property is deallocated. You do need the "copy" attribute because an NSString property could have been passed in as an NSMutableString. The "copy" guarantees that the original object will be kept around. Again, I apologize for the incorrect/misleading information I originally had here.

The reason you can access the instance variable someString as well as the property self.someString is that the @synthesize someString line creates an instance variable for the property and creates methods for getting and setting the value of it. However, it is recommended that you use the property instead of directly using the instance variable because by using the instance variable, you cannot let the parent object know that you've changed one of its properties.

Marguritemargy answered 13/3, 2013 at 11:57 Comment(2)
Note that since Xcode 4.4 if you don't explicitly use @synthesize, then the instance variable will implicitly be named _someString with the leading underscore.Refined
Using strong with strings is wrong. It is standard practice to use copy on things like NSString or NSArray where the caller could pass in the mutable subclass (NSMutableString or NSMutableArray) and then mutate it at a later point.Clasping

© 2022 - 2024 — McMap. All rights reserved.