【问题标题】:iPhone Memory Management with Properties of Singletons具有单例属性的 iPhone 内存管理
【发布时间】:2010-02-13 23:06:25
【问题描述】:

我似乎对内存管理的理解存在根本性的差距。下面的代码位于一个单例中,该单例在我的应用程序中被多次调用以解析从网络下载的数据。对于我下载的每篇文章,我分配一个可变字符串,然后进行大量解析,然后将文件写入文件系统,以便稍后在 UIWebView 中显示。

但是每次进入这个方法,我都会分配一个新的“articleString”。而且我从不释放这个字符串。我认为这是一个泄漏,但是如果我在这个方法的底部添加一个发布(在文件写入之后),我的应用程序在下次调用这个方法时会崩溃。我不明白它为什么会崩溃,因为下次调用它时会分配另一个 NSMutableString 。

更新:我确实在 dealloc 方法中发布了 articleString。但是似乎还是应该在这个方法结束的时候释放,因为每次进入都是alloc。

UPDATE:articleString在header中定义如下:

@property (nonatomic, retain) NSMutableString *articleString;

下面的 parseArticle 方法是一系列操作 articleString 的方法的占位符。

 self.articleString = [[NSMutableString alloc] initWithData:articleData encoding:NSUTF8StringEncoding];

 //Parse the article for display
 [self parseArticle];

 //Write the article string to a file for later display
 NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
 NSString *documentsDirectory = [paths objectAtIndex:0];
 NSString *path = [documentsDirectory stringByAppendingPathComponent:@"article.html"];
 NSLog(@"%@", articleString);
 [articleString writeToFile:path atomically:YES];

【问题讨论】:

  • 你对@property articleString的定义是什么?您还需要发布parseArticle 的内容,其中可能包含一些保留/释放错误。
  • 见上面编辑过的问题。谢谢。

标签: iphone cocoa memory-management memory-leaks


【解决方案1】:

我喜欢让属性为我处理这个问题。如果articleString 属性设置为retain,那么这很简单。

self.articleString = [[[NSMutableString alloc] initWithData:articleData encoding:NSUTF8StringEncoding] autorelease];

[self doStuff];

然后

- (void)dealloc {
    self.articleString = nil;
    [super dealloc]
}

当您设置一个新字符串时,文章字符串将被释放并正确保留。并且会在 dealloc 上清理掉。

【讨论】:

  • 为什么self.articleString = nil;而不是dealloc方法中的[articleString release]?
  • 因为将保留属性设置为 nil 会释放它。这是对其分配方式的直接赞美(没有明确的retain)。这会崩溃:[articleString release]; [articleString someMethod] 虽然这很有效,因为在 nil 上调用方法很酷:self.articleString = nil; [articleString doStuff]。而且,同样地,如果您已经发布了它,则此声明没有任何害处。一般来说,虽然它做同样的事情,但总体上更不容易出错并且更容易理解。
  • 作为一个坚定的规则,你永远不会释放一个属性,除非在 dealloc 方法中。属性合成访问器方法正在为您跟踪保留计数。任何直接释放属性的尝试几乎都会导致错误。
  • 相反,您应该将任何向半释放或半初始化对象发送消息的尝试视为错误。这包括访问者消息。今天它可能是一个综合访问器,但明天你可以用自定义访问器替换它,或者在子类中。始终在init 方法中直接保留/复制并分配给ivar,并在dealloc 中直接释放对象。
猜你喜欢
  • 2011-05-31
  • 2017-05-19
  • 1970-01-01
  • 2011-11-19
  • 1970-01-01
  • 1970-01-01
  • 2011-04-10
  • 2011-10-10
相关资源
最近更新 更多