如何处理值类型的递归

在我们的应用程序中,当我们需要共享状态时,我们可以使用引用类型。 例如,视图,视图控制器和模型控制器需要是引用类型。 但是,我们应用的模型必须是值类型,以便我们可以传递本地副本。 否则,您可能会遇到更改模型状态的问题,并在应用程序的其他位置产生副作用。 因为您的模型类型也是传递最多的模型类型,所以当它们是引用类型时,可能会对内存管理产生更大的影响。

Swift的问题在于,由于存在内存管理问题,它不允许使用递归值类型。 值类型分配在堆栈上,而不分配在堆上。 它们的大小必须固定,因为操作系统需要知道将它们放入堆栈的大小。 将它们放在堆栈上之后,它们的大小将无法增长,因为其他数据将被置于它们之上。 如果结构包含自身,则系统无法计算其大小。 这就是为什么Swift不允许递归值类型,并且您不能编写这样的代码的原因:

 结构TypeA { 
让其他:TypeA
}

或这个:

 结构TypeA { 
让其他:B型
}
 结构B型{ 
让其他:TypeA
}

有两种解决此问题的方法:

  • 集合提供足够的间接性以允许递归引用
  • 只有一个参考时使用协议

假设我们有两个结构。 一个用于用户 ,一个用于博客User结构具有一个属性,该属性包含该用户的所有已发布博客,该属性包含该用户的所有关注者,以及一个属性lastBlog(用于最近发布的博客)。 Blog结构具有此Blog作者的属性,类型为User 。 我们可以通过为其中一个用户创建协议来解决User结构的LatestBlog属性和Blog结构的author属性的递归引用问题。 在我们的Blog结构中。 属性博客User结构的关注者的收集类型提供了足够的间接方式来规避此问题:

  struct用户{ 
命名:字符串
var博客:[Blog]
var个关注者:[User]
var LatestBlog:BlogType?
}
  协议 BlogType {} 
  struct Blog:BlogType { 
日期:日期
内容:字符串
作者:用户
}