【问题标题】:How to manage memory for autorelease objects如何管理自动释放对象的内存
【发布时间】:2011-12-13 14:55:43
【问题描述】:

我致力于扑克牌类的实现,并创建了以下方法:

+ (id)cardWithCard:(Card *)newCard
{
Card *card = [[[Card alloc] initWithCard:newCard] autorelease];
return card;
}

我在这里使用自动释放方法,否则 Product->Analyze 会警告我潜在的泄漏。一切正常,直到变量 myCard(之前分配的)被分配了一个新值,如下所示:myCard = [Card cardWithCard:newCard] 被作为参数发送到不同的方法。原来它在那里被释放,我的应用程序崩溃了。 我应该如何解决这个问题?尽管有分析的警告,但仍要取消自动释放方法?

【问题讨论】:

    标签: objective-c memory-management autorelease


    【解决方案1】:

    每个方法或对象都应该负责保留它感兴趣的对象。
    它更容易维护。 (名称中包含allocnewcopy 的方法除外,它们将返回调用者负责的对象release。)

    所以您需要保留autorelease,因为在return 之后该方法不存在,并且无法对其调用release。
    调用cardWithCard 的对象应该retain 对象,如果它希望它比该特定方法的时间更长。

    代码应该是这样的

    self.myCard = [Card cardWithCard:newCard];
    

    这是myCard这样声明的情况

    @property (nonatomic, retain) Card * myCard;
    

    因此,在这种情况下,该属性将为您执行保留操作,并在您将新对象放入此属性中时释放该对象。 (如果你覆盖了自动生成的访问器,你需要自己在这些方法中管理它)

    如果出于某种原因您不想使用某个属性...好吧,这是您的选择 :-)
    您将需要执行以下操作:

    myCard = [[Card cardWithCard:newCard] retain];
    

    你以后会需要这样的东西

    [myCard release];
    

    如果不是采用相同的方法,分析器将编译,如果采用相同的方法,您可能不需要retain

    【讨论】:

    • 非常感谢您的详细解释。我在实践中得到的是:当我做这些@property (nonatomic, retain) Card * myCard;没有改变。 myCard 仍然在我传递给它的方法中被释放。这样做 - myCard = [[Card cardWithCard:newCard] 保留];已解决问题,应用程序不再崩溃,但现在我想知道我是否有泄漏(Analyze 说我没有)因为我将 myCard 保留在一个循环中但只释放一次。你怎么看?我现在有泄漏吗?
    • @AndreyChernukha 不要那样做!!!!您正在绕过您的@property,您需要执行self.myCard = something,以便调用该属性并执行它的魔法。如果您使用myCard = something,您将绕过您的@property,这就是为什么您需要额外的retain。如果您总是绕过属性,请不要费心声明它们,但这不是一个好方法,它更容易出错
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-13
    • 2012-07-02
    • 1970-01-01
    • 2011-04-27
    • 2011-01-11
    • 1970-01-01
    相关资源
    最近更新 更多