内存管理:这段代码是否有内存泄漏?

时间:2010-10-28 14:54:03

标签: ios memory-management memory-leaks

// 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;
}

strB会泄漏吗?它应该在ClassB dealloc方法中发布吗?

3 个答案:

答案 0 :(得分:3)

我假设你没有合成属性,你定义的自定义setter就是所有被调用的......如果这就是事实,那么你实际上是因为你没有保留你的属性而释放你的字符串

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) 

现在如果你试图访问classB strB属性,你可能会因为过度发布而崩溃

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


        }

如果你要在setter中保留字符串,那么你应该在classB dealloc中释放它。但实际上你必须要小心你编写setter的方式(你应该只是合成并让你为你生成属性),这里是setter实际上应该是什么样子

如果在实际设置之前它不是nil,你发布strB,它会检查a是否为nil,在这种情况下你只需将strB设置为nil,否则你将strB设置为a并保留

希望这有帮助

答案 1 :(得分:2)

您将属性定义为retain,但不保留字符串(只需使用@synthesize来定义getter和setter)

我认为你应该在ClassB的dealloc中释放strB

答案 2 :(得分:2)

是的,您必须在ClassB dealloc中添加一个版本,因为您在setter中对strB进行了保留。

对象“strB”生活:

  • NSString * strA = [[NSstring alloc] initWithString:@“test string”]; - > 1
  • [classB setStrB:strA]; - > 1
  • [strA release]; - > -1