2010-11-19 36 views
9

我确定我错过了对iOS内存管理的一些基本理解,尽管有大量的阅读和搜索,但我仍然没有得到它。iOS单身人士和内存管理

我在我的应用程序中使用了一个包含当前用户登录信息,从多个视图控制器访问的信息等的单例。它具有多个在应用程序中获取和设置的ivars。他们在声明和.h文件有产者像这样:

NSString *myString; 

和由保留像这样:

@property (non atomic, retain) NSString *myString; 

,并在实施synththesized。

我得到和在单这样的方法设置它们的值:

myString = @"value"; 

methodLocalString = myString; 

在其他地方,包括我的单身 - 称之为CurrentUser - 我导入它:

#import "CurrentUser.h"  

在我得到的单例之外,设置这样的:

[CurrentUser sharedCurrentUser].myString = @"Bob"; 

myOutsideString = [CurrentUser sharedCurrentUser].myString; 

这其中大部分的伟大工程的时候,用值在一个获取或设置到另一个适当的坚持。麻烦的是,有时当我以这种方式获得它们时,我发现它们已经被释放(崩溃应用程序),NSZombieEnabled谢天谢地告诉我。

我不明白的是他会如何发生。我认为这个单身人士永远不会被释放,因此保留单身人士的属性永远不会被释放。我会注意到,这个问题似乎更常见于像NSDate这样的非真实对象属性以及不能保留的int和BOOL等绝对非对象属性,但它也发生在对象属性中。

我对这里一无所知?并感谢您的耐心。

+0

很好的问题。等待澄清。 – harshalb 2010-11-19 04:57:49

+1

不要在'NSString'属性中使用'retain'。使用'copy'。 – 2010-11-19 08:32:51

+0

谢谢你的不在副本上。这应该是所有支持NSCopying的对象,对吧? – 2010-11-19 09:23:31

回答

14

您的问题是:

我得到和在单身这样设置其值的方法 :

myString = @"value";

当您直接分配到伊娃,而不是使用属性语法(self.myString = @"value"),您绕过了合成的setter方法,这意味着retain从不发生。

属性并不神奇。他们只是一些“”的语法糖。“访问以及合成getter/setter方法的能力,从而为您节省编写自己的繁琐工作。

self.myString = @"value"; 

[self setMyString:@"value"]; 

合成setMyString方法会做这样的事情只是速记:

if (myString != newValue) { 
    [myString release]; 
    myString = [newValue retain]; 
} 

(假设在@synthesize retain选项)

+0

这使*完美*感,谢谢! – 2010-11-19 05:14:22

0

Don't use singletons.您当前的问题是由...造成的简单的记忆管理误解,但单身模式只会让你长期头痛。

+1

感谢您的建议。我已阅读了十多篇关于利弊的文章,并对我的选择感到满意。 – 2010-11-19 13:16:19

+2

一般而言,iOS应用程序中的单身人士最终会令您头痛不已。但是,如果你小心,你可以使用它们。但是,你永远不应该做的一件事就是引用你的单例中的UIKit元素。我已经在许多项目中评论过开发人员使用单例,并且基本上任何时候单身持有引用UIKit对象或引用UIKit对象的其他对象的引用时,您最终都会在脚下拍摄自己。内存泄漏工具不会像这样捕获UIKit泄漏,并且您将留下一堆难以修复的循环引用。 – MoDJ 2011-06-09 20:59:44