内存泄漏 - 仪器,Objective-C

时间:2011-01-11 18:17:47

标签: objective-c uitableview memory uitextfield memory-leaks

我有一个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 * value;”的NSString而“valueTable”只是一个UITableView。当我测试内存泄漏时,我在“value = [[theTextField.text stringByReplacing ...”这一行上得到“100%”内存泄漏,我尝试删除该行上的“retain”。然而,后来当我呼吁“价值”时,它是零,这是不好的。

那么如何修复内存泄漏?什么是内存泄漏?谢谢!

3 个答案:

答案 0 :(得分:1)

正在泄露的内存是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

答案 1 :(得分:0)

稍后您应该在完成后释放value。例如,您可以在委托的dealloc方法中释放它:

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

请参阅Apple关于内存管理的文档。

答案 2 :(得分:0)

正如其他人所说,问题出在以下几行:

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