【问题标题】:iOS Singletons and Memory ManagementiOS 单例和内存管理
【发布时间】:2010-11-19 04:24:31
【问题描述】:

我确信我缺少对 iOS 内存管理的一些基本了解,尽管阅读和搜索了很多内容,但我仍然没有得到它。

我在我的应用程序中使用了一个单例,其中包含有关当前登录到其中的用户的信息、从多个视图控制器访问的信息等。它具有在整个应用程序中获取和设置的多个 ivars。它们在 .h 文件中声明和属性,如下所示:

NSString *myString;

并像这样保留:

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

并在实现中综合。

我在单例中的方法中获取和设置它们的值,如下所示:

myString = @"value";

methodLocalString = myString;

在其他地方我包含了单例——称之为 CurrentUser——我将其导入:

#import "CurrentUser.h"     

在单例之外我得到并设置它是这样的:

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

myOutsideString = [CurrentUser sharedCurrentUser].myString;

大多数情况下,这很有效,从一个获取或设置到另一个的值适当地持久化。问题是,有时当我以这种方式获取它们时,我发现它们已被释放(使应用程序崩溃),谢天谢地,NSZombieEnabled 告诉了我。

我不明白他是如何发生的。我认为单例永远不会被释放,因此单例的保留属性永远不会被释放。我会注意到这个问题似乎更常见于非真实对象属性(如 NSDate)和绝对非对象属性(如不能保留的 int 和 BOOL),但对象属性也会发生这种情况。

我在这里有什么不知道的?感谢您的耐心等待。

【问题讨论】:

标签: iphone cocoa-touch memory-management ios singleton


【解决方案1】:

你的问题是:

我在方法中获取并设置它们的值 在这样的单例中:

myString = @"value";

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

属性不是魔法。它们只是“。”的一点语法糖。访问,以及合成 getter/setter 方法的能力,以节省您编写自己的乏味。

self.myString = @"value";

只是简写

[self setMyString:@"value"];

合成的setMyString 方法将执行以下操作:

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

(假设@synthesize 上有retain 选项)

【讨论】:

    【解决方案2】:

    Don't use singletons.您当前的问题是由一个简单的内存管理误解引起的,但从长远来看,单例模式只会让您更加头疼。

    【讨论】:

    • 感谢您的建议。我现在已经阅读了十多篇关于利弊的文章,并且对我的选择感到满意。
    • 一般来说,iOS 应用中的单例最终会让你头疼。但是,如果你小心的话,你可以使用它们。但是,你永远不应该做的一件事是从你的单例中引用 UIKit 元素。我已经回顾了开发人员在许多项目中使用单例的情况,基本上任何时候单例持有对 UIKit 对象或其他引用 UIKit 对象的对象的引用,你最终都会自取其辱。内存泄漏工具不会像这样捕获 UIKit 泄漏,你会留下一堆难以修复的循环引用。
    猜你喜欢
    • 2016-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-15
    相关资源
    最近更新 更多