如何释放自己初始化的对象

How to release object which init it self

编写 Objective-C 时,了解内存的管理方式很重要,即使在 ARC 的帮助下也是如此。

这是一个代码片段(非 ARC):

(1)

NSAttributedString *tmpAttrbutedString = [[NSAttributedString alloc] initWithString:@"foo" attributes:@{NSFontAttributeName:[NSFont fontWithName:@"Heiti SC" size:13.0f]}];
// how should I release tmpAttributedString here?
tmpAttributedString = [[NSAttributedString alloc] initWithString:tmpAttributedString.string attributes:@{NSForegroundColorAttributeName:[NSColor redColor]}];
[tmpAttributedString release];

这是我目前为避免内存泄漏所做的工作:

(2)

NSAttributedString *tmpAttrbutedString = [[NSAttributedString alloc] initWithString:@"foo" attributes:@{NSFontAttributeName:[NSFont fontWithName:@"Heiti SC" size:13.0f]}];
NSString *tmpString = tmpAttrbutedString.string;
[tmpAttrbutedString release];

tmpAttributedString = [[NSAttributedString alloc] initWithString:tmpString attributes:@{NSForegroundColorAttributeName:[NSColor redColor]}];
[tmpAttributedString release];

我的问题是:

  1. 我应该如何释放(1)中的tmpAttributedString,只有一个NSAttributedString指针并且没有像(2)中的临时NSString?可能吗? (第二个 init 取决于第一个 init。)

  2. 编译器在场景(1)中会做什么?我的意思是 ARC 如何为它插入 release/autorelease?如果启用ARC,(1)中是否存在内存泄漏? (当然 release 的显式调用已通过 ARC 删除。)

谢谢!

ARC 的规则相对简单。如果您调用 allocnewcopy,那么 ARC 知道它需要在超出范围时对该对象调用 release。所有其他对象都假定为 autoreleased。 "Going out of scope" 表示 return 或重新分配变量。如果它看到一个变量被重新分配,它会在它被分配给其他东西之前隐式地调用 release 。如果你 return 一个变量,ARC 会对该变量进行 autorelease 调用,这样它就可以在方法的范围之外持续;任何其他未被 returned 但仍然存在的现有变量(不是自动释放的)将有一个隐含的 release 发送给它们。

Apple's official transition guide供参考。