Swift中的Post-Feed数据建模
这个问题是关于当你有几种类型的帖子时,为一个新闻提要(比如Twitter/Facebook/随便什么)存储一系列帖子的最佳方式。为了使事情更简单,让我们考虑一种情况,当你有2种类型的帖子(每个都有不同的单元UI):一个“大”的帖子(照片、文本…)和一个“小”的帖子,这更像是一个通知。如果您想在UI元素(collectionView/tableView)中同时显示这两种帖子,那么将这两种帖子都放在“posts”数组中非常方便,因此我们可以这样做:Swift中的Post-Feed数据建模,swift,polymorphism,protocols,data-modeling,Swift,Polymorphism,Protocols,Data Modeling,这个问题是关于当你有几种类型的帖子时,为一个新闻提要(比如Twitter/Facebook/随便什么)存储一系列帖子的最佳方式。为了使事情更简单,让我们考虑一种情况,当你有2种类型的帖子(每个都有不同的单元UI):一个“大”的帖子(照片、文本…)和一个“小”的帖子,这更像是一个通知。如果您想在UI元素(collectionView/tableView)中同时显示这两种帖子,那么将这两种帖子都放在“posts”数组中非常方便,因此我们可以这样做: protocol Post {
protocol Post {
var postID : String {get set}
var creatorID : String {get set}
var postType : PostType {get set} //<--- Custom enum that just has ".big" and ".small" in this case
//some other general things for the post may go here
}
struct BigPost : Post {
//All the post vars here
var postID : String
var creatorID : String
var postType : PostType = .big
//Some other things for this post type (just examples, they are not important)
var imageUrl : String
var countComments : Int
//etc
}
struct SmallPost : Post {
//All the post vars here
var postID : String
var creatorID : String
var postType : PostType = .small
//Some other things for this post type (just examples, they are not important)
var text : String
//etc
}
它是有效的,您只需要使用“postType”变量为每个post类型定义相应的单元格。我的问题是,这是一种好的方法吗?因为我考虑过实现diffing(例如,witch,deepDiff,这太棒了),所以当我们有很多帖子时,collectionView/tableView中的更新是有效的,但是,我该怎么做呢?因为我无法使我的Post协议符合其他一些“可扩散”协议,因为我无法声明[Post]类型的数组,即使我使smallPost和BigPost都符合该“可扩散”协议,“Post”数组中的元素仍然被编译器视为“Post”,因此我无法执行任何“diff”
也许多态性策略更好?你的想法是什么?看看类型转换- 您可以使smallPost和bigPost符合“可扩散”,创建数组
var posts : [Diffable] = [BigPost(), SmallPost(), SmallPost(), BigPost()]
然后检查它们的类型:
if let post = posts[0] as? SmallPost {
// do something
}
或
您不需要额外的属性(var postType:postType{get set})很好的方法,但不幸的是,在这种情况下,您不能这样做,因为“Diffable”通常有关联的类型(在DeepDiff的特殊情况下,协议名是DiffAware,并且也有关联的类型),所以您不能用它生成数组,您会遇到恼人的“协议只能用作一般约束”错误
if let post = posts[0] as? SmallPost {
// do something
}
if let post = posts[0] as? BigPost {
// do something
}