如果我在释放对象所属的池后释放对象会发生啥?

Posted

技术标签:

【中文标题】如果我在释放对象所属的池后释放对象会发生啥?【英文标题】:What might be happening if I release object, after releasing pool that object belongs to?如果我在释放对象所属的池后释放对象会发生什么? 【发布时间】:2014-09-19 09:51:10 【问题描述】:

我只是在问逻辑问题。如果我先释放池然后释放对象,对象会从内存中释放吗?例如,这是我的代码 sn-p:


[self performSelectorInBackground:@selector(setImage) withObject:nil];

-(void)setImage

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];

    NSString *strUrl = @"--some URL--";

    NSData *imageData = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:strUrl]];
    UIImage *myimage = [[UIImage alloc] initWithData:imageData];

    [pool release];
    [imageData release];

假设代码sn-p在非ARC环境下执行。

【问题讨论】:

【参考方案1】:

这很好,因为您从未将 imageData 对象添加到自动释放池中,因此池不会释放它。如果您像这样将 imageData 对象添加到自动释放池中:

[[[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:strUrl]] autorelease];

额外的版本会导致过度发布,您的应用可能会崩溃。 看起来你已经泄露了myImage,因为它从未发布过。

【讨论】:

如果在我的代码 sn-p 中使用 autorelease 会怎样?因为,pool 负责发送 release 消息。但是,在我的情况下,我在池释放自身后释放对象。如果我理解错了,请纠正我。 如果你将autorelease添加到imageData,那么当你创建它时,它的保留计数将为1,当自动释放池释放imageData时,保留计数将减少,它将是解除分配。如果您随后尝试释放imageData,您将遇到崩溃。如果您将autorelease 添加到myImage,它将正常工作。 好的,所以当执行到[imageData release]时,会找不到imageData对象并导致crash。【参考方案2】:

当您调用[pool release]; 时,添加到池中的自动释放对象不会立即释放。因此,当您显式调用 release 时,您的 imageData 的引用计数将减少 1。当池释放时,任何一个应用程序都会因实例被释放或消息发送到 nil 对象而崩溃。

【讨论】:

以上是关于如果我在释放对象所属的池后释放对象会发生啥?的主要内容,如果未能解决你的问题,请参考以下文章

释放数组时 NSMutableDictionary 中使用的对象的内存会发生啥?

Objective-C多线程,当一个对象在其方法被执行时被释放会发生啥? (以及如何预防?)

NSAutoreleaseNoPool():NSConcreteMutableData 类的对象 0x66ad9d0 自动释放,没有适当的池 - 只是泄漏

Objective-C 自动释放池不释放对象

*** __NSAutoreleaseNoPool():NSPathStore2 类的对象 0x926d620 自动释放,没有适当的池 - 只是泄漏

如果在 using 语句中发生异常,该对象是不是仍会被释放?