繁体   English   中英

指针设置为nil时,ARC不取消分配(使用工厂方法)

[英]ARC does not dealloc when pointer is set to nil (using factory methods)

编辑:下面定义的问题实际上是与此代码发生的:

int main(int argc, const char * argv[])
{
    @autoreleasepool
    {
        XYZPerson *myPerson = [XYZPerson person];
        myPerson = nil;
        NSLog(@"The end.");
    }
}

方法“ person”是工厂方法。


我有以下代码:

int main(int argc, const char * argv[])
{
    @autoreleasepool
    {
        XYZPerson *myPerson = [[XYZPerson alloc] init];
        myPerson = nil;
        NSLog(@"The end.");
    }
}

XYZPerson覆盖dealloc方法,以便使用NSLog打印出一些内容。 我希望上面的代码输出类似:

Dealloc!
The end.

但这不是我所期望的:

The end.
Dealloc!

我是在做错什么还是误解了ARC的概念?

ARC保证在编译时将自动引用对象。 进一步,提出了代码必须在算法上完全一致的要求(尝试通过强制转换在例如void*id之间转换时表现为错误-在ARC下,您必须限定此类强制转换的内存管理策略) 。

ARC不是垃圾收集器;它不是垃圾收集器。 没有扫描,没有线程,也没有停止世界的行为。 这意味着以诸如自动周期检测之类的代价为代价的行为更具可预测性。

尽管ARC保证可以自动管理对象的寿命,但ARC不保证其寿命超出“该对象的寿命至少应长于代码中使用的寿命,甚至更长”。

实际上,您可能会看到生命周期的变化,这取决于代码的优化级别以及所调用的工厂方法是否在ARC与手动保留释放[MRR]源文件中进行了编译。 并且寿命可能会在编译器和/或运行时的版本之间改变。

例如,调用工厂方法的ARC代码有时可能会使autorelease完全短路。

听起来很吓人,但这不是因为算法一致性要求。 由于不能存在模棱两可的行为(就像普通的旧MRR中那样),因此寿命可能会随着版本的变化而改变, 因此不会影响您的代码。

当然,这意味着您在dealloc方法之间不应具有顺序依赖性。 这不应该是繁重的要求,因为在MRR下,在dealloc方法之间具有顺序依赖性始终是一件令人讨厌的事情。

这是因为ARC仍然遵守Cocoa内存管理命名约定。 您可以像这样向您的工厂方法person添加属性: + (instancetype)person __attribute__((objc_method_family(new))); 因此ARC假定它返回的对象带有增加的保留计数,该计数需要与相应的发行版进行平衡。 然后,在将变量设置为nil后立即进行dealloc。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM