有没有办法将弱引用变为强引用?

时间:2015-08-19 00:18:01

标签: objective-c weak-references strong-references

我有一个对象被设置为另一个对象的委托,其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
}

由于没有其他任何东西引用委托,它最终会被取消分配,但是我希望它只要父对象就好,就像父对象有一个强引用一样。有没有一种简单的方法来实现这一目标?

1 个答案:

答案 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]];

但你不应该尝试to turn things upside down or inside out