NSString 的内存泄漏
我在这里阅读了几乎所有关于涉及 NSStrings 的内存管理的问题,但我无法真正解决这个问题。
@接口:
@property (nonatomic, retain) NSString *criticalTranscription;
@实现: viewDidLoad:
criticalTranscription = [[NSString alloc] init];
NSArray *paragraphs = [doc valueForKeyPath:@"critical.text"];
for(int i = 0; i < [paragraphs count]; i++)
{
criticalTranscription = [criticalTranscription stringByAppendingString:[[paragraphs objectAtIndex:i] valueForKey:@"p"]];
criticalTranscription = [criticalTranscription stringByAppendingString:@"\n\n"];
}
[transcription setText:criticalTranscription];
@XIB 一个带有 IBAction 的 UISegmentedControl 链接到:
- (IBAction) changeText:(id)sender
{
if(transcriptionSelector.selectedSegmentIndex == 1)
[transcription setText:diplomaticTranscription];
else
[transcription setText:criticalTranscription];
}
当我更改 UISegmentControl 的值时(加载后第一件事,没有其他运行),我遇到了这个错误(NSZombieEnabled=YES):
2011-07-07 01:10:43.639 Transcribe[404:707] *** -[CFString length]: message sent to deallocated instance 0x1189300
我在回溯中看不到任何相关内容。如果没有 NSZombieEnabled, criticalTranscription 仅指向随机数组或其他内容。没有进一步使用该变量或任何版本。
我进行了分析,没有发现任何可疑的泄漏。
有什么问题吗?
I read almost every Question here on SO about memory management that involves NSStrings, but I can't really solve this problem.
@interface:
@property (nonatomic, retain) NSString *criticalTranscription;
@implementation:
viewDidLoad:
criticalTranscription = [[NSString alloc] init];
NSArray *paragraphs = [doc valueForKeyPath:@"critical.text"];
for(int i = 0; i < [paragraphs count]; i++)
{
criticalTranscription = [criticalTranscription stringByAppendingString:[[paragraphs objectAtIndex:i] valueForKey:@"p"]];
criticalTranscription = [criticalTranscription stringByAppendingString:@"\n\n"];
}
[transcription setText:criticalTranscription];
@XIB
A UISegmentedControl with an IBAction linked to:
- (IBAction) changeText:(id)sender
{
if(transcriptionSelector.selectedSegmentIndex == 1)
[transcription setText:diplomaticTranscription];
else
[transcription setText:criticalTranscription];
}
When I change the value of the UISegmentControl (first thing right after loading, nothing else runs), I run into this error (NSZombieEnabled=YES):
2011-07-07 01:10:43.639 Transcribe[404:707] *** -[CFString length]: message sent to deallocated instance 0x1189300
I can't see anything relevant in the backtrace. Without NSZombieEnabled criticalTranscription just points to random arrays or something else. There is no further usage of the variable or any releases.
I ran analyze without any suspicious leaks.
What's the problem?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
问题在于您正在用您不拥有的字符串覆盖对您拥有的字符串的引用。
但是,不要使用这种方法,因为它会用不必要的字符串污染自动释放池。相反,使用可变字符串并将字符串附加到单个可变字符串实例。
此外,为了利用该属性的内置内存管理,您需要使用
self.riticalTranscription
而不仅仅是riticTranscription
。如果没有self.
,您将直接使用实例变量。The problem is that you are overwriting a reference to a string that you own with one that you don't own.
However, don't use this approach, because it pollutes the autorelease pool with unnecessary strings. Instead, use a mutable string and append strings to the single mutable string instance.
Also, in order to utilise the property's built-in memory management, you need to use
self.criticalTranscription
and not justcriticalTranscription
. Without theself.
, you are using the instance variable directly.在 for 循环中,
您将 CriticalTranscription 设置为自动释放的字符串对象,但不保留它,从而导致火焰死亡。
您可以保留它或使用
@property(nonatomic, copy)NSString *riticTranscription;
的属性,并使用该属性而不是 ivar。In your for loop
you are setting
criticalTranscription
to an autoreleased string object but not retaining it, thus the flaming death.You could retain it or use a property with
@property(nonatomic, copy)NSString *criticalTranscription;
and use the property rather than the ivar.两个问题:
要解决此问题,最简单的方法是将 CriticalTranscription 更改为 NSMutableString。然后你可以这样做:
…或者,
另请注意,一旦完成,你需要在
riticTranscription
上调用release
,无论是在- 的末尾viewDidLoad
或其相应的-viewDidUnload
中。Two problems:
To fix it, the easiest way is to change
criticalTranscription
to an NSMutableString. Then you can do:…alternatively,
Also note that you need to call
release
oncriticalTranscription
once you’re done with it, either at the end of your-viewDidLoad
or in its corresponding-viewDidUnload
.