2010-10-28 135 views
0
// 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方法中發佈嗎?內存管理:這段代碼是否有內存泄漏?

回答

2

是的,您必須在ClassB dealloc中添加一個版本,因爲您在setter中對strB進行了保留。

對象 「STRB」 壽命:

  • 的NSString * STRA = [[NSString的頁頭] initWithString:@ 「測試字符串」]; - > +1
  • [classB setStrB:strA]; - > +1
  • [strA release]; - > -1
+0

有一個保留「聲明「,但執行者沒有保留。 – 2010-10-28 17:12:39

+0

我不認爲你在這裏是正確的。使用自定義setter不會增加strB上的保留計數。因此,代碼不會按原樣泄漏,但也不會按照您的要求執行,因爲稍後您將無法訪問classB.strB,因爲它已發佈。 – 2010-10-29 10:04:57

2

你定義爲保留財產,但不保留字符串(只是用@synthesize來不必定義getter和setter)

而且我認爲你應該在ClassB的

的dealloc的釋放STRB
3

我假設你還沒有合成的財產和您定義的自定義二傳手是所有被調用......如果那是事實,那麼你實際上是OVER釋放你的字符串,因爲你不保留你的財產

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


     } 

如果要保留在二傳手的字符串,然後是你應該

發佈它在classB dealloc中。但實際上你必須小心你編寫你的setter的方式(你應該只是綜合並讓它爲你生成),這裏是setter的外觀應該是怎樣的

在這裏,如果你沒有發佈strB零之前,你實際上設置它,它會檢查,看看是否是零在這種情況下,您只需設置STRB到零,否則你設置STRB到並留住

希望這有助於

+0

謝謝,我忘了在我的示例中添加@synthesize行。我想這解釋了爲什麼我的應用程序中有bazilion內存泄漏和問題。 – sniurkst 2010-10-28 15:31:26

+0

setStrb的這個例子:*不是*自定義設置器應該是什麼樣子。如果strB和a都指向相同的字符串,這是完全可能的,那麼setter將在保留它之前釋放字符串,如果幸運的話,會導致EXC_BAD_ACCESS。自定義設置器應如下所示: - (void)setStrb:(NSString *)a { [a retain]; [strB release]; strB = a; } 或者,您可以在分配之前自動釋放strB。然而,你這樣做,你不能在保留a之前釋放strB。 – 2010-11-07 22:08:00