autorelease 对象啥时候释放?

Posted

技术标签:

【中文标题】autorelease 对象啥时候释放?【英文标题】:When is the autorelease object released?autorelease 对象什么时候释放? 【发布时间】:2018-07-29 11:36:05 【问题描述】:

我用下面的代码测试了一下,发现autorelease objc永远不会释放。

__weak id ref;

@implementation ViewController

- (void)viewDidLoad 
    [super viewDidLoad];
    NSString *str = [NSString stringWithFormat:@"test"]; // add autoreleasePool
    ref = str;


- (void)viewWillAppear:(BOOL)animated 
    [super viewWillAppear:animated];
    NSLog(@"viewWillAppear:%@",ref); // result test


- (void)viewDidAppear:(BOOL)animated 
    [super viewDidAppear:animated];
    NSLog(@"viewDidAppear:%@",ref); // result test


- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event 
    NSLog(@"%@",ref); // If I click long after,But it has not been released

【问题讨论】:

【参考方案1】:

[NSString stringWithFormat:] 不会向您承诺自动释放池中的对象。它向您承诺一个您不必释放的对象。在这种情况下,它会返回一个常量字符串,并且常量字符串永远不会被破坏。还可以免费返回缓存值,或与其他读取器共享的值、标记指针或单例。 NSNumber 有很多这样的优化。

对于基本问题,当本地自动释放池被耗尽时,一个release 将被发送到之前发送到该池上对象的每个autorelease 的对象。这是否会破坏对象取决于在其上放置了哪些其他保留。

我希望这样的值更接近您的预期,但没有任何承诺:

[NSString stringWithFormat:@"something a little long and computed: %d", rand()]

【讨论】:

还要注意,在 ARC 下,retain/release/autorelease 语义可以随编译器的变化而变化。例如,您很可能会在调试版本与发布版本中看到更多的自动发布流量。 MRC下,autorelease对象什么时候释放?我知道runloop迭代中的autorelease对象结束了迭代了很多次。所以autorelease对象已经释放了。但是我试了一下,发现结果不是我所期望的。 使用 MRC,就像我在上面所说的那样“当本地自动释放池耗尽时,对于之前发送到该池中对象的每个自动释放,都会向对象发送一个释放。”是的,有一个自动释放池在每个运行循环结束时被耗尽。但我在这里所说的一切都适用于 MRC(它适用于 MRC 更多而不是适用于 ARC)。没有保证 stringWithFormat: 的返回值是“一个自动释放的对象”。只是一个承诺,你不必释放它。 此外,即使是带有自动释放功能的对象,在池耗尽时也可能不会被销毁。承诺将release 发送给它。这可能不会破坏对象。 非常感谢!我想我明白了。

以上是关于autorelease 对象啥时候释放?的主要内容,如果未能解决你的问题,请参考以下文章

autorelease,函数完成时释放对象

29-oc自动释放池

75. Autorelease机制及释放时机

75. Autorelease机制及释放时机

iOS 过早释放对象 - 可能与 Autorelease 和 Copy 混淆

在 Objective-C 中如何处理 Autorelease 池中的对象?