iPhone内存管理

时间:2010-01-16 16:14:19

标签: iphone memory-management

我正在开发一个应用程序,我想确保我正确地管理内存并释放我应该做的一切。在我的viewDidLoad方法中,我在确定要应用于视图的背景(用于国际化)时分配一些变量,如果我不释放它们,应用程序就可以正常工作。

问题是,如果我发布变量,应用程序将崩溃。 viewDidLoad中的代码如下:

// Set the background image based on the phone's preferred language
NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];
NSString *backgroundImageName = [[NSString alloc] init];
backgroundImageName = [NSString stringWithFormat:@"background-%@.png",language];
self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:backgroundImageName]];

... do some more initialization stuff ...

// IF THE FOLLOWING ARE RELEASED THE APP WILL CRASH!!!
//[backgroundImageName release];
//[language release];

为什么发布backgroundImageName和语言变量会导致应用程序崩溃?

3 个答案:

答案 0 :(得分:6)

NSString *language = [[NSLocale preferredLanguages] objectAtIndex:0];

此处,language不需要发布,因为objectAtIndex:会为您自动释放它。按照惯例,如果您alloc编辑,new编辑或copy编辑它,则您拥有一个对象,否则您不会。

self.view.backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:backgroundImageName]];

此处,UIColor对象确实需要发布(因为你alloc编辑了它。)

NSString *backgroundImageName = [[NSString alloc] init];
backgroundImageName = [NSString stringWithFormat:@"background-%@.png",language];

此处[[NSString alloc] init]返回的字符串确实需要释放(因为您alloc编辑了它。但是,下一行更改backgroundImageName以指向新的自动释放字符串,丢失对原始字符串的最后一次引用而不释放它(内存泄漏)。 backgroundImageName不应该被释放,因为它已经自动释放了。

您可以通过释放UIColor并消除未使用的字符串来避免泄漏。例如:

NSString *backgroundImageName = [NSString stringWithFormat:@"background-%@.png",language];

......和......

UIColor* backgroundColor = [[UIColor alloc] initWithPatternImage:[UIImage imageNamed:backgroundImageName]];
self.view.backgroundColor = backgroundColor;
[backgroundColor release];

答案 1 :(得分:0)

简短回答: 当你使用没有单词init的构造函数创建一个对象时,你不负责释放它

请参阅this了解更多说明

内存management guide也是一个很好的资源,可以更好地了解目标c中的内存管理

答案 2 :(得分:0)

你没有创建语言字符串;你刚回来参考。只有在其中具有“new”,“copy”或“alloc”的方法(按照惯例)才返回非自动释放的对象。对于所有其他方法,假设您将丢弃该变量,因此如果您想保留它,您必须保留它。另一方面是:除非您保留它们,否则不应释放这些返回的对象。

此代码中的另一个问题是backgroundImageName被分配了两次。第一次初始化正在丢失。摆脱它,只保留第二个,并摆脱两个 - 释放电话,他们是不需要的。