when not under ARC, for the following code,
.h
@property (nonatomic, retain) NSString *s;
.m
NSString *m = [NSString stringWithString:@"Hellow, World"];
s = [m retain];
// later on
s = nil; <-- will this release the ref count on the string and hence get the string released?
When used like this (i. e. by accessing the instance variable directly), then no, it won’t. However, if you use the property’s accessor method (
[self setS:nil];orself.s = nil;), then yes, it will.Also note that releasing an object and freeing its memory are two completely different things. An object is deallocated only when it has no more strong references – i. e. you have the last reference to it and then you release it. If you release it but it has other references (by having been retained previously), then it won’t be deallocated yet, only its reference count will be decremented by one.
Furthermore, if you have a retained property, such the one in your example, you must not do 1. access the underlying instance variable directly, 2. do stuff like
Why? Because the first line is simply unnecessary – really, why
- [NSString stringWithString:]? You’re creating a constant string, then create an exact copy of it – it’s just superfluous. If Cocoa’s designers were noobs, this line would also waste memory – two exact copies of the same immutable string. Fortunately, whoever implemented NSString was prepared for this situation and made this method check its argument for being a constant and returning it without doing anything if it is – so you get back the same pointer, but with a few extra calls toobjc_msgSend– that’s not something you want.The second line is also wrong – again, you don’t use the backing ivar as-is. Also, the property is declared
retainfor a reason – if you set an object to your property, that object will be retained by the setter method – no need to manually retain it.All in all, you’d better write
instead.