Управление памятью: есть ли в этом коде утечка памяти? - PullRequest
0 голосов
/ 28 октября 2010
// 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? Должен ли он быть выпущен в методе Classloc dealloc?

Ответы [ 3 ]

3 голосов
/ 28 октября 2010

Я предполагаю, что вы не синтезировали свойство, и пользовательский установщик, который вы определили, - это все, что вызывается ... Если это так, то вы на самом деле ПОЛНОСТЬЮ освобождаете свою строку, потому что не сохраняете свое свойство

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) 

теперь, если вы попытаетесь получить доступ к свойству strB классаB, у вас, вероятно, произойдет сбой из-за чрезмерного выпуска

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


        }

Если вы хотите сохранить строку в установщике, тогда да, вы должны освободить ее в classB dealloc. Но на самом деле вы должны быть осторожны с тем, как пишете свой установщик (вам, вероятно, следует просто синтезировать и позволить сгенерировать свойство для вас), вот как на самом деле должен выглядеть установщик

Здесь вы выпускаете strB, если он не равен nil, прежде чем вы на самом деле его установите, он проверяет, является ли a nil, в этом случае вы просто устанавливаете strB в nil, иначе вы устанавливаете strB в a и сохраняете

Надеюсь, это поможет

2 голосов
/ 28 октября 2010

Да, вы должны добавить выпуск в Deloc ClassB, потому что вы делаете сохранение для strB в установщике.

Срок службы объекта "strB":

  • NSString * strA =[[NSstring alloc] initWithString: @ "тестовая строка"];-> + 1
  • [classB setStrB: strA];-> + 1
  • [релиз strA];-> -1
2 голосов
/ 28 октября 2010

Вы определяете свойство как retain, но не сохраняете строку (просто используйте @synthesize, чтобы не определять геттер и сеттер)

И я думаю, вы должны выпустить strB в dealloc класса B

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...