我有一个对象被设置为另一个对象的委托,其delegate
属性很弱。
- (YYService *)service
{
XXHandler *handler = [[XXHandler alloc] init];
// YYService's "delegate" property is weak
return [[YYService alloc] initWithDelegate:handler];
// The XXHandler is deallocated because there are no strong references to it
}
由于没有其他任何东西引用委托,它最终会被取消分配,但是我希望它只要父对象就好,就像父对象有一个强引用一样。有没有一种简单的方法来实现这一目标?
答案 0 :(得分:0)
为什么要解决"该问题是子类YYService
,为子类提供了一个额外的强属性,并在-initWithDelegate:
中设置了一个。
但是这个"解决方案"会加深你的设计中的问题,而不是解决它。
让我们来看看,为什么代表们通常会保持弱势:
委托类具有一般性或无性行为,可能不适合该类#39;用户的情况,我。即如果发生了什么事(操作完成,发生错误,$ 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]];