objective-cgetter-setterinitwithcoder

Why does initWithCoder need self.property?


I tend to regularly use self.property in my Objective C code when accessing variables as I understand that this makes use of the getter/setter methods (either explicitly coded or automatically generated).

Another coder told me recently that it's best to use _property instead, throughout the code. But my understanding is that _property is really only for use in init and dealloc methods.

Today I found a bug in some code that uses initWithCoder. I was using _property in the initWithCoder method and had to change it to self.property. This was when setting an NSData object. Here is the original code:

@property (nonatomic, strong) NSData *data;

- (id)initWithCoder:(NSCoder *)decoder {
    self = [super init];
    if (!self) {
        return nil;
    }
    _data = [decoder decodeObjectForKey:@"data"];
    return self;
}

And I had to change it to this, to get it to work:

@property (nonatomic, strong) NSData *data;

- (id)initWithCoder:(NSCoder *)decoder {
    self = [super init];
    if (!self) {
        return nil;
    }
    self.data = [decoder decodeObjectForKey:@"data"];
    return self;
}

My question is - why is initWithCoder the exception here? If it's generally accepted that it's best to use _property in an init method, then why is initWithCoder different?

It seems now like the general rule is:

Use self.property except in init/dealloc methods, where _property should be used (except in initWithCoder, where self.property should be used).

Is this correct?


Solution

  • I do not think it is generally true that you must use properties in initWithCoder:. I have a lot of code (and have seen a lot) where ivar access is used in initWithCoder:, if that may help as a hint.

    If you were not using ARC, then your implementation setting _data would have a problem in that the object would be soon autorelased. But under ARC your code is correct.

    So, I tend to think that something different was causing the issue in your case. As an example, if you use KVO, then you should use properties, otherwise the KVO-related notifications are not generated. You should provide more information as to what exactly led you to think that the assignment to _data was the cause of the issue, and about the visible effect of that issue in other parts of your code.