内存泄漏 - 仪器、Objective-C

发布于 2024-10-11 11:16:53 字数 604 浏览 3 评论 0原文

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

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

I have a UITextField and in the delegate class I have a UITableView. Here is the code:

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

    [valueTable reloadData];

    return YES;
}

"value" is an NSString declared at the top of my class as "NSString *value;" and "valueTable" is just a UITableView. When I test for memory leaks, I am getting a "100%" memory leak on the line "value = [[theTextField.text stringByReplacing..." and I tried removing the "retain" on that line. However then later on when I called upon "value," it was nil, which is not good.

So how can I fix the memory leak? And what is the memory leak? Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

伴我老 2024-10-18 11:16:53

被泄漏的内存是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 = ...;
...

另外,因为您总是会拥有调用该方法后保留的内存,当您的类被释放时,您需要释放 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

The memory that is being leaked is the memory pointed to by value.

Every time your text field changes, the method stringByReplacingCharactersInRange... is returning an autoreleased NSString object. You are correct to retain it, so that it isn't deallocated. The problem, is that you now own memory somewhere. (You own that NSString by retaining it.)

The next time that method is called, when the user changes the text in that field, you're pointing value to a completely different memory location. The original memory that you had retained still exists, and will continue to persist forever. (Since you never released it.)

It's very important to match any retain method calls with an associated release. You could do either:

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

OR

You can define the NSString *value as a property on your class, like:

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

/* Implementation file */
@synthesize value;

Then simply use:

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

Also, since you're always going to have retained memory after that method has been called, you'll need to release value when your class is deallocated, as was mentioned in another answer:

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

Edit: It sounds like you should definitely read Apple's memory management guide before continuing:
http://developer.apple.com/library/mac/#documentation/cocoa/conceptual/MemoryMgmt/MemoryMgmt.html

喜爱皱眉﹌ 2024-10-18 11:16:53

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

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

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

You should release value later on when you're done with it. For example, you can release it when in the delegate's dealloc method:

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

see Apple's documentation on memory management.

纵性 2024-10-18 11:16:53

正如其他人所提到的,问题出在以下行:

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

As the others have mentioned, the problem is in the following line:

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

The issue with this code is that you are not releasing the old value of value before assigning the new value. Changing the code to the following should fix the leak, provided there are no other unforeseen problems elsewhere:

- (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];
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文