编辑:实际上下面定义的问题发生,此代码:
int main(int argc, const char * argv[])
{
@autoreleasepool
{
XYZPerson *myPerson = [XYZPerson person];
myPerson = nil;
NSLog(@"The end.");
}
}
该方法“人”是一个工厂方法。
我有以下代码:
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
方法。 这不应该是具有之间顺序依赖性的繁重要求dealloc
方法下MRR一直是个讨厌的东西。
这是因为ARC依然尊重可可内存管理的命名约定。 您可以添加属性到你的工厂方法person
是这样的: + (instancetype)person __attribute__((objc_method_family(new)));
因此ARC假定它返回的对象带有一个递增保留计数,将需要用相应的释放平衡。 之后,然后立即设置变量为nil将发生的dealloc。