0

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?

3 Answers 3

1

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;
}
Sign up to request clarification or add additional context in comments.

Comments

0

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".

2 Comments

Forgot the synthesize to note that there are accessors. Question updated.
The problem with using accessors in init or dealloc is that they can have side effects or assume invariants that don't hold in a partially (de)constructed object. Apple explicitly says not to, so if you're using their generated accessors, you should probably follow their advice.
0

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;
}

2 Comments

Would you always copy any type instead of just simple assign? What types would you not copy?
@HowardSpear: Strings, arrays and dictionaries at least should almost always be copied. The reason you want to copy is that these classes have mutable variants, and you usually don't want to be sharing a mutable string with somebody else. Having shared mutable objects in your instance variables means they can change without warning, which can lead to some weird behavior.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.