views:

89

answers:

3
// ClassA.m
NSString *strA = [[NSstring alloc] initWithString:@"test string"];
ClassB *classB = [[ClassB alloc] init];

[classB setStrB:strA];
[strA release];
// classB will be released later

// ClassB.h
@property (nonatomic, retain) NSString *strB;

// ClassB.m

// custom setter
-(void) setStrB:(NSString *)newStr {
    strB = newStr;
}

Will strB leak? Should it be released in ClassB dealloc method?

+2  A: 

You define the property as retain, but you don't retain the string (just use @synthesize to not have to define getter and setter)

And I think you should release strB in dealloc of ClassB

Benoît
+1  A: 

Yes you have to add a release in the ClassB dealloc cause you make a retain on strB in the setter.

Object "strB" life :

  • NSString *strA = [[NSstring alloc] initWithString:@"test string"]; -> +1
  • [classB setStrB:strA]; -> +1
  • [strA release]; -> -1
MathieuF
there is a retain in the "declaration", but the implementation of the setter has no retain.
fluchtpunkt
I don't think you are correct here. Using the custom setter does not up the retain count on strB. So the code is not leaking as is, but not doing what you want either, because you will not be able to access classB.strB later on, because it is released.
Vincent Osinga
+3  A: 

I am assuming you havent synthesized the property and the custom setter you defined is all that gets called...If thats the fact, then you are actually OVER releasing your string because you are not retaining your property

NSString *strA = [[NSstring alloc] initWithString:@"test string"]; //string with +1 ref
ClassB *classB = [[ClassB alloc] init];

[classB setStrB:strA]; //doesnt increase the ref count
[strA release]; //string with 0 ref count (which means OS will reclaim the memory allocated for the string) 

now if you try to access classB strB property you will probably have a crash due to over release

If you were to retain the string in the setter, then yes you should release it in classB dealloc. But actually you have to be careful the way you write your setter (you should probably just synthesize and let the property be generated for you), here is how the setter should actually look like

-(void)setStrb:(NSString*)a
{
   if(strB)
      [strB release];
    if(a==nil)
       strB=nil;
     else
      strB=[a retain]; 

}

Here you are releasing strB if it isnt nil before you actually set it, it checks to see if a is nil in which case you just set strB to nil, else you set strB to a and retain

Hope this helps

Daniel
Thank you, I forgot to add @synthesize line in my example. I guess this explains why I have bazilion memory leaks and issues in my application.
sniurkst