我正在开发一个应用程序,我想确保我正确地管理内存并释放我应该做的一切。在我的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和语言变量会导致应用程序崩溃?
答案 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)
答案 2 :(得分:0)
你没有创建语言字符串;你刚回来参考。只有在其中具有“new”,“copy”或“alloc”的方法(按照惯例)才返回非自动释放的对象。对于所有其他方法,假设您将丢弃该变量,因此如果您想保留它,您必须保留它。另一方面是:除非您保留它们,否则不应释放这些返回的对象。
此代码中的另一个问题是backgroundImageName被分配了两次。第一次初始化正在丢失。摆脱它,只保留第二个,并摆脱两个 - 释放电话,他们是不需要的。