ARC和自定义deallocs

时间:2011-10-10 20:47:10

标签: objective-c

出于好奇/兴奋,我一直在阅读有关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了;所以你什么时候需要?

3 个答案:

答案 0 :(得分:4)

据我所知,您应该将ARC视为编译器中内置的静态分析器,在需要时合成保留和释放调用(这也是ARC代码向后兼容运行的设备的原因) iOS4的)。

因此,样本中的netService_无法自动停止。在这种情况下,您需要编写自己的dealloc。

委托问题很有意思,在iOS5术语中它将是一个弱属性,因此它可能在dealloc上设置为nil ...不确定但它很有趣!

您必须自己处理的另一种情况是您拥有不是objective-c对象的句柄对象,例如对于Core Foundation对象,您需要编写CFRetainCFRelease s自己。

答案 1 :(得分:2)

我认为如果你需要做些什么来清理一个对象,其他而不是发布它,那么对于自定义的dealloc方法来说,这是公平的游戏。

因此,在您自己的netService_示例中,调用setDelegate:stop是合理的,但是没有必要调用release,因为ARC负责这一点。

答案 2 :(得分:0)

很明显,ARC不会知道你的[netService_ stop];行。您必须自己加入,因为它不标准且与retain / release无关。

dealloc运行后,ARC将释放所有strongweak属性(以及__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,则相同的行为仍然存在,但输出不同,因为测试用例不会保留弱引用。