When I have my own init method with synthesized properties as such:
@property (copy, nonatomic) NSString *bookName;
@property (strong, nonatomic) NSMutableArray *book;
When I want to initialize with my own custom initializer I am shown to write it like this:
-(id) initWithName: (NSString *)name
{
self = [super init]
if (self) {
bookName = [NSString stringWithString: name];
book = [NSMutableArray array];
}
return self;
}
Now I want to clarify something. I know why it uses the stringWithString method, because instead of just passing the address to the passed in string it’ll create a new object so that it owns the string itself. Could I not also just write it like so:
self.bookName = name;
Doing this should use the synthesized method and actually create a new object right? Basically both accomplish the same thing. I ask because there are methods else where that show doing it both ways so I just want to make sure there are no other issues that could crop up with using one way or the other. They both appear to do the same thing in different ways (using the synthesized method vs directly modifying the class variable but creating a new object in memory for it).
I’ll also point out that this is in an ARC environment.
(Note that I am assuming the above is ARC code; otherwise it is incorrect.)
You should almost always use accessors to access your ivars (even in ARC). However, there is some controversy about whether
initshould use accessors or directly access its ivars. I have switched sides in this controversy, but it’s not an obvious decision IMO.The primary argument for not allowing
initto use accessors is that it is possible that a future (unknown) subclass might create side-effects in the accessor. You generally don’t want side effects happening during yourinit. For instance, you probably don’t want to post change notifications when you’re setting something to its initial value, and it is possible that your object is in an “undefined state” and would be dangerous to read at this point.That said, and while this argument did finally sway me, I have never once encountered this situation on numerous projects of various sizes with several teams. I have many times encountered developers failing to
retainwhen setting their ivars ininit(as you have done above, and which would crash if it is not ARC). This is why for a long time I recommended using accessors even ininit. But in theory it does create a danger, particularly if you are a closed-source framework writer (i.e. Apple). And so, for my own code I now avoid accessors ininit. If I were working with a more junior teams on older retain/release code, I would probably still have them use accessors ininit. It’s just avoided so many crashes in my experience.It is not controversial that you should avoid calling accessors in
dealloc, however. This definitely can lead to bizarre side-effects in the middle of destroying your object.