出于好奇/兴奋,我一直在阅读有关ARC的任何信息,但我有一个问题似乎无法找到答案。不确定人们是否可以因为NDAs或其他原因而回答这个问题,但无论如何我都会问。 (那里有很多信息.......)
ARC宣传的一件事是你不再需要编写dealloc方法了。凉。但这是真的吗?
如果我有一个NSNetService或其他东西,通常在我的dealloc中我会写
- (void)dealloc
{
[netService_ setDelegate:nil];
[netService_ stop];
[netService_ release];
[super dealloc];
}
ARC现在负责吗?或者不够聪明,不知道这样的东西?如果它不够聪明,不知道那些东西(意味着我仍然需要在某些情况下编写自定义deallocs)我是否必须释放所有的ivars?或者只是那些不简单的版本?
- (void)dealloc
{
[netService_ setDelegate:nil]; // if these 3 lines are necessary...
[netService_ stop];
[netService_ release];
[myString_ release]; // would this one still be? or would ARC know to automagically add this
[super dealloc]; // seems this is forbidden in ARC
}
我想我的问题实际上归结为:ARC说在大多数情况下你不再需要写deallocs了;所以你什么时候需要?
答案 0 :(得分:4)
据我所知,您应该将ARC视为编译器中内置的静态分析器,在需要时合成保留和释放调用(这也是ARC代码向后兼容运行的设备的原因) iOS4的)。
因此,样本中的netService_
无法自动停止。在这种情况下,您需要编写自己的dealloc。
委托问题很有意思,在iOS5术语中它将是一个弱属性,因此它可能在dealloc上设置为nil ...不确定但它很有趣!
您必须自己处理的另一种情况是您拥有不是objective-c对象的句柄对象,例如对于Core Foundation对象,您需要编写CFRetain
和CFRelease
s自己。
答案 1 :(得分:2)
我认为如果你需要做些什么来清理一个对象,其他而不是发布它,那么对于自定义的dealloc方法来说,这是公平的游戏。
因此,在您自己的netService_
示例中,调用setDelegate:
和stop
是合理的,但是没有必要调用release
,因为ARC负责这一点。
答案 2 :(得分:0)
很明显,ARC不会知道你的[netService_ stop];
行。您必须自己加入,因为它不标准且与retain
/ release
无关。
在dealloc
运行后,ARC将释放所有strong
和weak
属性(以及__strong
和__weak
iVars。
这是一些测试代码,只是为了看看会发生什么:
@interface TestClass : NSObject
@property (nonatomic, strong) TestClass *anotherTestObject;
@end
@implementation TestClass
@synthesize anotherTestObject;
- (void)dealloc {
NSLog(@"I am deallocing %d", self.hash);
}
@end
我的测试:
TestClass *thing1 = [[TestClass alloc] init];
NSLog(@"thing 1 %d", thing1.hash);
thing1.anotherTestObject = [[TestClass alloc] init];
NSLog(@"thing 2 %d", thing1.anotherTestObject.hash);
这将打印出类似这样的内容
thing 1 1450176
thing 2 1459984
I am deallocing 1450176
I am deallocing 1459984
由于测试代码末尾只有一个对象被自动释放(thing1
),您可以立即告诉其他人thing2
已被释放(因为它位于{{{ 1}}属性)。但是,如果您覆盖strong
,则会发现ARC 不将其设置为setAnotherTestObject
,而只是直接释放它。你不能在ARC中覆盖nil
,否则我也可以证明这一点;)
如果我调整代码并使用release
而不是weak
,则相同的行为仍然存在,但输出不同,因为测试用例不会保留弱引用。