2015-08-19 43 views
0

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

为什么你不能让代表成为强有力的参考? – dudeman

+0

显示一些相关的代码来为您的问题提供上下文。 – rmaddy

+0

@MikeAtNobel,我没有提到它的问题,但与委托的类是从第三方库 – ide

回答

0

容易为什么要“解决”这个问题是子类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]]; 

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

相关问题