2011-01-11 47 views
0

我有一个UITextField,并在委托类中有一个UITableView。代码如下:内存泄漏 - 仪器,Objective-C

- (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”。然而,后来当我呼吁“价值”时,它是零,这是不好的。

那么我该如何解决内存泄漏?什么是内存泄漏?谢谢!

回答

1

正在泄漏的内存是由value指向的内存。

每次您的文本字段发生变化时,方法stringByReplacingCharactersInRange...都会返回一个自动发布的NSString对象。你保留它是正确的,所以它不会被释放。问题在于你现在拥有自己的记忆。 (您通过保留它来拥有该NSString。)

下次调用该方法时,当用户更改该字段中的文本时,您将value指向完全不同的内存位置。你保留的原始记忆仍然存在,并将继续保持下去。 (因为你从来没有发布过。)

这是非常重要匹配任何retain方法调用与相关release。你可以这样做既:

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

OR

您可以定义NSString *value为你的类的属性,如:

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

/* Implementation file */ 
@synthesize value; 

然后只需使用:

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

另外,因为你总是会保留mem这种方法被称为ORY后,你需要释放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]; 
} 

编辑:这听起来像你一定要阅读苹果的内存管理指南继续之前: http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/MemoryMgmt/MemoryMgmt.html

+1

第一个例子中的'if(value)`语句是不必要的。如果`value`是`nil`,那么`[value release];`什么都不会做,如果不是,它会被释放。 – kubi 2011-01-11 18:28:37

0

稍后,您应该在完成后发布value。例如,你可以释放它在代理的dealloc方法时:

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

看到苹果的内存管理文档。

+0

这是唯一正确的,如果你假设stringByReplacingCharactersInRange方法被调用一次。例如,如果该方法被调用4次,那么您将该内存泄漏了3次,并且仅适当地释放它一次。 (当他的课程被释放时) – 2011-01-11 18:28:43

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