“解决”这个问题的简单原因是子类YYService
化,给子类一个额外的强属性并将其设置在-initWithDelegate:
.
但是这个“解决方案”会加深你设计中的一个问题,而不是解决这个问题。
让我们看看,为什么代表通常被弱持有:
委派类有一个可能不适合该类用户的情况的一般(或没有)行为,即如果发生某些事情。(操作完成,发生错误,$whatever)因此委托类为您提供了自定义行为的机会,包括运行自定义代码。委托与子类化竞争,但与子类化的区别在于每个实例(而不是每个类)和运行时(而不是编译时)。
因为它在每个实例的基础上工作,所以创建委托的实例通常会强烈地持有委托实例。此代码知道应该应用于委托实例的自定义:
-(void)createDelegate
{
self.delegating = [Delegating new]; // I create and hold the instance strongly
delegating.delegate = self; // I customize it
}
然后委托实例不能强持有委托,因为这将是一个保留循环。
在您的代码段中不起作用,因为-service
返回新创建的委托实例。即使可以返回两个实例,我也不喜欢它,因为创建委托对象和安装委托将是一个两步操作,即使它在语义上是一步操作。所以如果你没有self
作为委托人,你应该用一种方法完成整个安装过程:
-(void)installService
{
self.handler = [[XXHandler alloc] init]; // Hold the handler strongly
self.service = [[YYService alloc] initWithDelegate:handler];
}
如果您不知道充当委托的具体实例对象,请将其作为参数传递:
-(void)installServiceWithDelegate:(id)delegate
{
self.delegate = delegate;
self.service = [[YYService alloc] initWithDelegate:delegate];
}
…
[self installServiceWithDelegate:[YourConcreteClass new]];
但是你不应该试图把事情颠倒过来或翻过来。