Утечка памяти - Инструменты, Objective-C - PullRequest
0 голосов
/ 11 января 2011

У меня есть UITextField, а в классе делегата у меня есть UITableView. Вот код:

- (BOOL) textField: (UITextField *)theTextField shouldChangeCharactersInRange: (NSRange)range replacementString: (NSString *)string {    
    value = [[theTextField.text stringByReplacingCharactersInRange:range withString:string] retain];

    [valueTable reloadData];

    return YES;
}

"value" - это NSString, объявленная в начале моего класса как "NSString * value;" и "valueTable" это просто UITableView. Когда я проверяю утечки памяти, я получаю «100%» утечку памяти в строке «value = [[theTextField.text stringByReplacing ...», и я попытался удалить «retain» в этой строке. Однако потом, когда я обратился к «стоимости», это было ноль, что нехорошо.

Так как я могу исправить утечку памяти? А что за утечка памяти? Спасибо!

Ответы [ 3 ]

1 голос
/ 11 января 2011

Утечка памяти - это память, на которую указывает value.

Каждый раз, когда изменяется ваше текстовое поле, метод stringByReplacingCharactersInRange... возвращает автоматически освобожденный объект NSString.Вы правы, чтобы сохранить его, чтобы он не был освобожден.Проблема в том, что у вас сейчас есть память где-то.(Вы владеете этой строкой NSString, сохранив ее.)

При следующем вызове этого метода, когда пользователь изменяет текст в этом поле, вы указываете value на совершенно другую область памяти.Первоначальная память, которую вы сохранили, все еще существует и будет существовать вечно.(Поскольку вы никогда не выпускали его.)

очень важно сопоставлять любые вызовы retain метода с соответствующими release.Вы можете сделать:

...
if (value) {
   [value release];
}
value = ...;
...

ИЛИ

Вы можете определить NSString *value как свойство вашего класса, например:

@property (nonatomic, retain) NSString *value);

/* Implementation file */
@synthesize value;

Затем просто используйте:

...
self.value = ...;
...

Кроме того, поскольку у вас всегда будет сохраненная память после вызова этого метода, вам нужно будет освободить value, когда ваш класс освобожден, какбыло упомянуто в другом ответе:

- (void)dealloc {
    // Only do *one* of the two following releases

    // (1) If you're not using properties:
    [value release];

    // (2) If you are using properties:
    self.value = nil;

    [super dealloc];
}

Редактировать: Похоже, что вы обязательно должны прочитать руководство по управлению памятью Apple, прежде чем продолжить: http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/MemoryMgmt/MemoryMgmt.html

0 голосов
/ 11 января 2011

Как уже упоминалось, проблема заключается в следующей строке:

value = [[theTextField.text
       stringByReplacingCharactersInRange:range withString:string] retain];

Проблема с этим кодом заключается в том, что вы не освобождаете старое значение value перед присвоением нового значения.Изменение кода на следующее должно исправить утечку, при условии, что в другом месте нет других непредвиденных проблем:

- (BOOL)textField:(UITextField *)theTextField
       shouldChangeCharactersInRange:(NSRange)range
           replacementString:(NSString *)string {

    NSString *newValue = [[theTextField.text
       stringByReplacingCharactersInRange:range withString:string] retain];
    [value release];
    value = newValue;

    [valueTable reloadData];

    return YES;
}

- (void)dealloc {
   [value release];
   [super dealloc];
}
0 голосов
/ 11 января 2011

Вы должны отпустить value позже, когда закончите с ним. Например, вы можете освободить его, когда в методе делегата dealloc:

- (void)dealloc {
    [value release];
    // other memory management code...
    [super dealloc];
}

см. Документацию Apple по управлению памятью.

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