代码之家  ›  专栏  ›  技术社区  ›  Matthew Frederick

iOS单例与内存管理

  •  9
  • Matthew Frederick  · 技术社区  · 14 年前

    我确信我对iOS内存管理缺少一些基本的理解,尽管我读了很多书,也做了很多搜索,但还是没有得到。

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

    NSString *myString;
    

    并被保留如下:

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

    并在实现中进行了综合。

    我在singleton的方法中获取并设置它们的值,如下所示:

    myString = @"value";
    

    methodLocalString = myString;
    

    在其他地方我包括单身汉 当前用户 --我导入它:

    #import "CurrentUser.h"     
    

    在单曲外,我得到并设置成这样:

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

    myOutsideString = [CurrentUser sharedCurrentUser].myString;
    

    大多数情况下,这工作得很好,从一个获取或设置到另一个获取或设置的值都会适当地持久化。问题是,有时当我以这种方式获得它们时,我发现它们已经发布(崩溃了应用程序),NSZombieEnabled感谢地告诉我。

    我不知道他怎么会这样。我认为singleton永远不会被释放,因此,singleton的保留属性永远不会被释放。我会注意到,这个问题似乎更常见于非真实对象属性,比如NSDate,而绝对不是对象属性,比如不能保留的int和BOOL,但是它也会发生在对象属性上。

    我对这里一无所知吗?谢谢你的耐心。

    2 回复  |  直到 14 年前
        1
  •  14
  •   David Gelhar    14 年前

    你的问题是:

    我用方法获取并设置它们的值 像这样的单身汉:

    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];
    }
    

    (假设 保持 选择@synthey)

        2
  •  0
  •   zoul    14 年前

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