2009-04-18 61 views
9

这段代码很简单,对吗?我不知道是否应该保留通过init方法传入的委托。关于代表的问题

@interface SomeClass : NSObject { 
    SomeClassDelegate *someClassDelegate; 
} 
-(id)initWithDelegate:(SomeClassDelegate *)delegate; 
@end 

@implementation SomeClass 
-(id)initWithDelegate:(SomeClassDelegate *)delegate 
{ 
    [delegate retain]; // should I be doing this? 
    someClassDelegate = delegate; 
} 
-(void)dealloc 
{ 
    [delegate release]; // obviously only do this if I DO need to retain it 
    [super dealloc]; 
} 
@end 

我最初的想法是否定,但是这段代码似乎提示否则。我知道我不能依赖保留计数,但我想知道处理代表的正确方法。

// self's retain count is 1 
NSURLConnection *connection = [[NSURLConnection alloc] initWithRequest:req delegate:self]; 
// the retain count is now 2, did the init of URLConnection retain self? 
+1

NSURLConnection有点特殊。这并不是因为它保留了委托,而是在连接期间保留它,因为阻止接收委托消息的唯一方法是取消连接。即通常一个不保留一个委托,NSURLConnection的这种行为是一个实现细节;不是你应该依赖或通常模仿的东西。 此外,有一个委托_class_是不寻常的。通常你声明一个委托协议。 – 2009-04-19 14:53:51

+0

感谢迈克,这解释了我所看到的。 – Jab 2009-04-19 15:56:39

回答

11

不,一般来说,你不应该保留代表。由于委托已经有了对象的引用,所以如果你保留了委托,你就会创建一个循环引用。同样,出于同样的原因,你可以假设你的对象在代理销毁之前被销毁。

检出thesearticles有关使用/实现代表的更多信息。

编辑:有一些例外,其他人已经指出。

1

正如说,你通常不应该保留委托。但是,在多线程环境中,即使仅仅是方法调用的持续时间,您通常也必须保留所需的所有内容,以确保它不会在后台失效。例如,如果(实际上并非如此),-[NSURLConnection initWithRequest:delegate]创建了一个线程可能保留的线程(然后可能会自动释放)其参数。实际上,NSURLConnection是一个特殊情况,因为它在连接期间保留其代表。