Objective-C 对象的分配/释放

Posted

技术标签:

【中文标题】Objective-C 对象的分配/释放【英文标题】:alloc/release of Objective-C objects 【发布时间】:2011-02-27 23:16:30 【问题描述】:

我有 Util 类如下。

@implementation Util

- (NSString*) getTodayString


    NSDate *today = [NSDate date];
    NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
        // display in 12HR/24HR (i.e. 11:25PM or 23:25) format according to User Settings
    [dateFormatter setDateFormat:@"YYYY/MM/dd"];
    NSString *now = [dateFormatter stringFromDate:today];

    [dateFormatter release]; ///???
    [today release]; //???
    return now;


@end

我使用类

- (void)awakeFromNib

    Util *ut = [[Util alloc] init];
    NSString* now = [ut getTodayString];
    NSLog(@"User's current time in their preference format:%@",now);

    [currentTime setObjectValue:now];
    [now release]; ///???
    [ut release];

我在释放对象时感到困惑。

在getTodayString ::

第一季度。 [dataFormatter 发布] 有必要吗? Q2。 【今日发布】有必要吗?

我想我不需要释放它们,因为我没有分配自己。如果是真的,这些对象什么时候被释放?

在 awakeFromNib ::

第三季度。 [ut 发布] 有必要吗? Q4。 [现在发布] 有必要吗?

我想我必须在明确创建对象时释放ut,但不要担心now 对象。

如何确定对象何时被释放? 有了python/C#/Java,人们就不再关心这种内存释放了。如果我不关心它们,Objective-C 也可以吗?

【问题讨论】:

【参考方案1】:

第一季度。 [dataFormatter 发布] 是 必要的? Q2。 [今天发布] 是 有必要吗?

dataFormatter:是的,你分配/初始化了它。今天:不,它是从工厂方法自动返回的。

第三季度。 [ut 发布] 有必要吗? Q4。 [现在发布]有必要吗?

同样的,

ut:是的,你分配/初始化了它。现在:不,它是从工厂方法自动返回的。

如何确定何时是 对象被释放了?

它在调用release时释放,如果调用autorelease,则在下一次运行自动释放池时调用release

如果我用 Objective-C 也可以吗 不关心他们?

不,这不好。如果您自己不清理,您将有大量内存泄漏,在 ios 环境中,这意味着您的应用程序完全关闭。在一个 Mac 应用程序中,这可能会导致消耗大量内存而不是一个好公民。这是假设一个非垃圾收集环境。即大多数。

我猜您的问题的核心是您不确定何时负责调用 release 以及何时获得 autoreleased 对象(或者更确切地说,何时负责调用对象的 release )。这是约定俗成的。如果您调用的任何方法返回的对象包含以下词:init/copy,那么调用 release 不是您的责任。如果你保留,你就会释放(在我看来,可能还有更多规则要遵循,但这是第一个真正开始理解这一点的规则)。如果你曾经调用 alloc/init/copy,那么你必须在某个时候调用release

一位伟大的老师是在 Xcode 中构建和分析。这将很快指出您在哪里搞砸了,并真正有助于了解发生了什么。

【讨论】:

避免对从类方法中自动释放的对象做出假设。始终考虑对象所有权,即“我拥有这个对象吗?我是从名称中带有newcopyalloc 的方法中获得的吗?”【参考方案2】:

您是否关心objective-c 中的内存管理取决于您使用的环境。如果你使用垃圾回收,你不必担心,但垃圾回收在 mac 上默认不启用,在 iOS 上根本不可用。什么时候需要发布的基本规则:

如果您从中获取它的方法以 alloc 或 init 开头,或者包含单词 copy,那么您拥有它并且必须释放它。 如果您明确保留一个对象,您就拥有它并且必须释放它。 如果该方法不包含 alloc、init 或 copy,您可以假定它已被自动释放。将来某个时候会自动释放,如果你想在当前方法返回后使用它,你需要保留它。

当然,当它们自动释放返回的对象时,这些也取决于遵循这些规则的任何第三方代码。

【讨论】:

init 不会影响对象的保留计数,只会影响alloc。否则,您需要释放它两次。 @dreamlax 不,但这表明您拥有该对象。【参考方案3】:

memory management rules 简单明了。不要考虑保留数量,始终考虑所有权。当你问自己“我应该释放这个对象吗?”时,问自己“我拥有它吗?”。牢记规则,最终它们将成为第二天性。

遵守规则非常重要。如果你忽略它们,你不拥有的对象可能会在你完成它们之前被释放(例如将你不拥有的对象分配给实例变量,它们可能会在自动释放池耗尽后被释放)。此外,如果忽略它们,最终会导致可怕的内存泄漏。

【讨论】:

以上是关于Objective-C 对象的分配/释放的主要内容,如果未能解决你的问题,请参考以下文章

为 Objective-C 数据对象分配内存的问题

Objective-C:内存泄漏与自动释放的多重分配?

ios学习路线—Objective-C(堆(heap)和栈(stack))

条件分配/释放? 【Objective-c与Cocos2D】

[学习笔记—Objective-C]《Objective-C-基础教程 第2版》第九章 内存管理

Objective-C的内存管理