Skip to main content
 首页 » 操作系统

swift之如何解决此循环引用初始化错误

2024年01月01日40youxin

我有一个带有嵌套结构 MultipleChoiceAnswers 的类 Question。在初始化 Question 时,我也初始化了 MultipleChoiceAnswers,为其提供了对 Question 实例的引用。然后,我想将 MultipleChoiceAnswers 实例分配给 Question 实例的属性 answers。

这是一个概述:

struct Answer { 
  let value:Double; 
  let isCorrect:Bool; 
} 
 
class Question { 
  struct MultipleChoiceAnswers { 
    let question:Question; 
    let answers:[Answer]; 
  } 
 
  let answers:MultipleChoiceAnswers; 
 
  init( possibleAnswersCount:UInt ) { 
    let answers:[Answer]; 
    /* 
      here I generate some Answer instances 
      that get appended to the answers Array 
    */ 
    self.answers = MultipleChoiceAnswers( question: self, answers: answers ); // <-- error 
  } 
} 

但是,这会导致错误:

Variable 'self.answers' used before being initalized

这是有道理的。不过,我能以某种方式解决这个错误吗?我正在考虑用 weak 或 unowned 来解决这个问题(最好是后者,因为它应该是 strong 保证的非 nil 引用),但我认为我还没有完全理解逻辑,因为将 MultipleChoiceAnswers 更改为:

struct MultipleChoiceAnswers { 
  unowned let question:Question; 
  let answers:[Answer]; 
} 

... 无法解决错误。

如何解决此错误,同时保持 strong 保证非 nil 循环引用?

P.S.:老实说,我什至还不完全确定我是否真的需要这个循环引用开始,但是由于这个暂定的实现引发了这个错误,我很好奇关于可能的解决方案。

请您参考如下方法:

只需在此处添加 !:

let answers:MultipleChoiceAnswers! 

answers 在将 self 传递给另一个函数之前需要有一个值。通过将 answers 声明为隐式展开的可选项,您可以为其指定默认值 nil。满足要求,你走吧。因为你确实在 init 完成之前给了它一个值,所以你永远不会遇到不小心解包 nil 的问题。 (当然,您应该始终小心使用 !。)

这在 "Unowned References and Implicitly Unwrapped Optional Properties" 中讨论在 Swift 编程指南中。