0

I'm currently developing an iOS application which was started by another developer.

Usually, I make a property for every instance variable (assign for int, bool etc. / retain for all classes).

So in my projects, this line causes a leak:

myVar = [[NSString alloc] init]; (alloc/init +1, retain in setter +1, release in dealloc -1 => +1)

So I use:

NSString *tmpMyVar = [[NSString alloc] init];
[self setMyVar: tmpMyVar];
[tmpMyVar release];

Or:

NSString *tmpMyVar = [[[NSString alloc] init] autorelease];
[self setMyVar: tmpMyVar];

In this new project, the previous developer didn't use @property/@synthesize so I'm wondering what will be the result of the previous line of code in this context (it doesn't call setter I guess)? Memory Leak?

The previous developer releases variable in dealloc method, just like me.

Thank you very much!

2 Answers2

2

Since it directly assigns the instance variable to the allocated object it's retain count is 1 (because, like you said, a setter isn't called). And because it's released in dealloc, it's all balanced out. So no memory leaks.

So in my projects, this line causes a leak:

myVar = [[NSString alloc] init]; (alloc/init +1, retain in setter +1, release in dealloc -1 => +1)

No,it wouldn't even in your projects, because, as you pointed out, no setter is used.

Also, when using properties, it is the recommended way to access instance variables directly in the init method, instead of using setters.

To inspect for questionable memory-leaks like your example, also use the clang static analyzer or instrument's leak tool.

Community
  • 1
  • 1
Mario
  • 4,530
  • 1
  • 21
  • 32
  • When I say "in my projects, this line causes a leak", It means in my projects which use @property/@synthesize, not in this project. So even if the method of the other developer doesn't cause leak, is it a good method? – Thomas Lupo Aug 21 '12 at 09:17
  • 1
    Af @Mario says, that code will not leak even in your project. You are accessing myVar directly, not through the setter, therefore that code would be correct and not leak. `myVar = [[NSString alloc] init];` is the preferred way to initialize the ivar in an init* method, regardless of the presence or absence of setters/getters and property declarations. – Analog File Aug 21 '12 at 09:45
  • In this project it will not causes a leak because of the absence of setter (no retain / no +1) but in projects which use property / synthesize, it causes a leak to use myVar = [[NSString alloc] init]; (alloc/init +1, implicit setter's call +1, release in dealloc -1) ? No ? – Thomas Lupo Aug 21 '12 at 10:04
  • 1
    No still! Please look at what has been repeatedly said! iVar = [[NSString alloc] init] and later (eg in dealloc) [iVar release] doesn't leak! Never! There is no "implicit" setter call as you said. A setter is called either [self setIVar: ...] or self.iVar = ... . iVar = ... is no setter but directly accessing the instance variable! – Mario Aug 21 '12 at 10:45
  • Thank you very much! It was a confusion between iVar = [[NSString alloc] init] and self.iVar = [[NSString alloc] init] – Thomas Lupo Aug 21 '12 at 12:10
  • @ThomasLupo: When using an instance variable directly, remember to release `myVar` prior to assigning it. Otherwise, if it already pointed to an object, then *that* object will be leaked. A synthesized setter does this for you. – newacct Aug 21 '12 at 18:30
0

You need to look at the other developer's setter implementation. Make sure they release the existing value and retain the new value; something like:

- (void)setMyString:(NSString *)string
{
    [string retain];
    [_string release];    // ivar
    _string = string;
}

The only advantage to implementing your own setter/getter methods is to do something (other than setting the ivar) when a value is set. If the methods don't do anything like this then why not change all implementations to @property/@synthensize?

trojanfoe
  • 120,358
  • 21
  • 212
  • 242