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
对象。
【问题讨论】:
【参考方案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 中构建和分析。这将很快指出您在哪里搞砸了,并真正有助于了解发生了什么。
【讨论】:
避免对从类方法中自动释放的对象做出假设。始终考虑对象所有权,即“我拥有这个对象吗?我是从名称中带有new
、copy
或alloc
的方法中获得的吗?”【参考方案2】:
您是否关心objective-c 中的内存管理取决于您使用的环境。如果你使用垃圾回收,你不必担心,但垃圾回收在 mac 上默认不启用,在 iOS 上根本不可用。什么时候需要发布的基本规则:
如果您从中获取它的方法以 alloc 或 init 开头,或者包含单词 copy,那么您拥有它并且必须释放它。 如果您明确保留一个对象,您就拥有它并且必须释放它。 如果该方法不包含 alloc、init 或 copy,您可以假定它已被自动释放。将来某个时候会自动释放,如果你想在当前方法返回后使用它,你需要保留它。当然,当它们自动释放返回的对象时,这些也取决于遵循这些规则的任何第三方代码。
【讨论】:
init
不会影响对象的保留计数,只会影响alloc
。否则,您需要释放它两次。
@dreamlax 不,但这表明您拥有该对象。【参考方案3】:
memory management rules 简单明了。不要考虑保留数量,始终考虑所有权。当你问自己“我应该释放这个对象吗?”时,问自己“我拥有它吗?”。牢记规则,最终它们将成为第二天性。
遵守规则非常重要。如果你忽略它们,你不拥有的对象可能会在你完成它们之前被释放(例如将你不拥有的对象分配给实例变量,它们可能会在自动释放池耗尽后被释放)。此外,如果忽略它们,最终会导致可怕的内存泄漏。
【讨论】:
以上是关于Objective-C 对象的分配/释放的主要内容,如果未能解决你的问题,请参考以下文章
ios学习路线—Objective-C(堆(heap)和栈(stack))
条件分配/释放? 【Objective-c与Cocos2D】