Howard Spear
Howard Spear

Reputation: 551

Using setters for assignment in init methods (objective-c)

I know that the correct convention to assign values in a class's method is to not use the setter version.

Given you have an init method like this:

// Class header 
@property (nonatomic, weak) id <DelegateType> delegate;
@property (nonatomic, strong) NSString *stringData;

@synthesize delegate = _delegate;
@synthesize stringData = _stringData;

- (id)initWithParams:(NSString *)aString delegate:(id<DelegateType>)aDelegate
{
    // initialization happens here
}

Pre-ARC, you would ensure the correct retain policy with:

stringData = [aString retain];
self.delegate = aDelegate;

With ARC, how would do the assignment and ensure that the ivars are not released too early?

Because you don't know what kind of work maybe happening behind the scenes in the case of a setter override, I was under the impression that you can't do:

self.stringData = aString

What is the correct init pattern?

Upvotes: 0

Views: 1031

Answers (3)

Ankit Thakur
Ankit Thakur

Reputation: 4749

Since you are using properties as

// Class header 
@property (nonatomic, weak) id <DelegateType> delegate;
@property (nonatomic, strong) NSString *stringData;

@synthesize delegate = _delegate;
@synthesize stringData = _stringData;

So as per ARC, weak object is working like assign. But "strong" is basically not working like retain, because retain only increase the reference count, and with ARC, objects of strong type are definatly exist, till the instance of that class exist.

So in init method

it should be

- (id)initWithParams:(NSString *)aString delegate:(id<DelegateType>)aDelegate
{
// now _stringData and _delegate are getter instance of property variables. so either you can use self.stringData and self.delegate or _stringData and _delegate.
    _stringData = aString;
    _delegate = aDelegate;
}

Upvotes: 1

Chuck
Chuck

Reputation: 237110

Just assign to the ivar. ARC will take care of the retains and releases according to the variable's memory management policy (__strong, __weak or __unsafe_unretained). That's the point of ARC. So your code sample would be:

- (id)initWithParams:(NSString *)aString delegate:(id<DelegateType>)aDelegate
{
    stringData = aString;
    delegate = aDelegate;
}

As an aside, though, you should probably be copying that string instead of retaining. So you'd declare the setter as @property (nonatomic, copy) NSString *stringData; and the implementation of the init method would be:

- (id)initWithParams:(NSString *)aString delegate:(id<DelegateType>)aDelegate
{
    stringData = [aString copy];
    delegate = aDelegate;
}

Upvotes: 0

DrummerB
DrummerB

Reputation: 40211

You can, and in fact you should (in most cases) use accessors to access your ivars even in your implementation with ARC. It's more intelligent then you'd think. There will be no ivars released "too early".

Upvotes: 0

Related Questions