Objective c 调用release是否会触发自动释放对象的释放?

Objective c 调用release是否会触发自动释放对象的释放?,objective-c,ios,memory-management,autorelease,Objective C,Ios,Memory Management,Autorelease,以下 NSImage *image = [[UIImage imageNamed:@"foo.png"] retain]; ... [image release]; 我的理解是,从imageNamed返回的对象应该是自动删除的。但由于对象上有一个保留,然后是一个显式释放。显式释放不仅会减少ref计数,而且还会触发整个对象的释放,而不是等待稍后GC的释放。假设在发出release调用时,iOS将首先尝试减少对象上的ref计数,然后发现当时没有其他主体引用该对象,因此它决定释放分配的内存。这是正确

以下

NSImage *image = [[UIImage imageNamed:@"foo.png"] retain];
...
[image release];

我的理解是,从imageNamed返回的对象应该是自动删除的。但由于对象上有一个保留,然后是一个显式释放。显式释放不仅会减少ref计数,而且还会触发整个对象的释放,而不是等待稍后GC的释放。假设在发出release调用时,iOS将首先尝试减少对象上的ref计数,然后发现当时没有其他主体引用该对象,因此它决定释放分配的内存。这是正确的理解和假设吗?

这不是正确的假设。该版本将在概念上否定保留。但是,您无法知道任何其他可能在那里浮动的ref计数。如果您的保留是唯一的,那么它将立即被销毁。事实并非如此

因为我们知道我们得到的是一个自动释放的对象,所以我们知道我们的retain引用不是唯一的引用。来自自动释放源的原始引用将保留,直到当前自动释放池排空。因此,你的假设在这里是有缺陷的:

当发出释放呼叫时,iOS将首先尝试减少ref 数一数该对象,然后发现没有其他人引用该对象 对象,因此它决定释放分配的内存

…因为原始自动释放的引用将保留

一般来说,您不应该对对象的确切释放时间做出任何假设。只需担心如何平衡你自己的保留数量,并相信事情会解决的。在本例中,可能存在的引用远不止您自己的retain和假定的AUTORELASE。这些框架可以在幕后自由地保留和释放它们想要的一切,只要事情保持平衡


最后,使用ARC并忘记所有这些:

这不是一个正确的假设。该版本将在概念上否定保留。但是,您无法知道任何其他可能在那里浮动的ref计数。如果您的保留是唯一的,那么它将立即被销毁。事实并非如此

因为我们知道我们得到的是一个自动释放的对象,所以我们知道我们的retain引用不是唯一的引用。来自自动释放源的原始引用将保留,直到当前自动释放池排空。因此,你的假设在这里是有缺陷的:

当发出释放呼叫时,iOS将首先尝试减少ref 数一数该对象,然后发现没有其他人引用该对象 对象,因此它决定释放分配的内存

…因为原始自动释放的引用将保留

一般来说,您不应该对对象的确切释放时间做出任何假设。只需担心如何平衡你自己的保留数量,并相信事情会解决的。在本例中,可能存在的引用远不止您自己的retain和假定的AUTORELASE。这些框架可以在幕后自由地保留和释放它们想要的一切,只要事情保持平衡


最后,使用ARC并忘记所有这些:

不,这是不正确的

此外,您对内存管理术语的理解有点松散,因此您的问题有点混乱

详细讨论所有这些方面对于一篇SO文章来说太多了

自动释放池不是垃圾收集。将其视为一组对象。自动释放对象时,该对象将添加到池中。当池被耗尽时,它基本上对池中的每个对象调用release,因此称为autoreleasepool

因此,如果您有一个已自动释放的对象,并且您在没有匹配释放的情况下进行了额外的retain调用,则自动释放池将不会释放该对象。它只会像预期的那样释放它一次

如果保留对该对象的其他引用,则该对象将仍然存在于自动释放池之外


多次调用retain/release只会增加和减少计数。直到计数达到零,对象才会解除锁定。

否,这是不正确的

此外,您对内存管理术语的理解有点松散,因此您的问题有点混乱

详细讨论所有这些方面对于一篇SO文章来说太多了

自动释放池不是垃圾收集。将其视为一组对象。自动释放对象时,该对象将添加到池中。当池被耗尽时,它基本上对池中的每个对象调用release,因此称为autoreleasepool

因此,如果您有一个已自动删除的对象,并且您进行了额外的重新设置 在没有匹配释放的调用中,自动释放池不会释放该对象。它只会像预期的那样释放它一次

如果保留对该对象的其他引用,则该对象将仍然存在于自动释放池之外


多次调用retain/release只会增加和减少计数。直到计数达到零,对象才会解除锁定。

没有垃圾回收。严格地说,这是一个计算自身引用的对象。当一个对象被创建时,它给自己一个1的引用计数。但在本例中,创建对象ImageName:-的方法将对象放入自动释放池。这意味着该池是1引用的所有者,它将在该方法完成后的稍后时间自动释放该引用

当一个对象的引用计数下降到0时,它会通过运行dealloc方法来销毁自己

将retain发送到autorelease池所拥有的映像意味着存在另一个引用-另一个所有者-然后计数将为2,但是您不应该考虑对象的内部绝对数,而应该只考虑您的所有权

池在任何情况下都将发送release,但如果您尚未释放通过发送retain获得的所有权声明,则此发布本身不会将ref计数降至0,因此对象不会被销毁

由于您确实发送了发布,您已经放弃了您的声明,并且自动释放池将负责其所有权-但稍后,当您发送发布时,情况并非如此-导致映像被破坏


简而言之,不,您发送的释放不会更改自动释放池的操作。它仍然拥有该对象,并且在运行循环结束时仍然向其发送release。

没有垃圾回收。严格地说,这是一个计算自身引用的对象。当一个对象被创建时,它给自己一个1的引用计数。但在本例中,创建对象ImageName:-的方法将对象放入自动释放池。这意味着该池是1引用的所有者,它将在该方法完成后的稍后时间自动释放该引用

当一个对象的引用计数下降到0时,它会通过运行dealloc方法来销毁自己

将retain发送到autorelease池所拥有的映像意味着存在另一个引用-另一个所有者-然后计数将为2,但是您不应该考虑对象的内部绝对数,而应该只考虑您的所有权

池在任何情况下都将发送release,但如果您尚未释放通过发送retain获得的所有权声明,则此发布本身不会将ref计数降至0,因此对象不会被销毁

由于您确实发送了发布,您已经放弃了您的声明,并且自动释放池将负责其所有权-但稍后,当您发送发布时,情况并非如此-导致映像被破坏

简而言之,不,您发送的释放不会更改自动释放池的操作。它仍然拥有该对象,并在运行循环结束时向其发送release