首页 > 解决方案 > Swift 中的 Post Feed 数据建模

问题描述

当您有多种类型的帖子时,这个问题是关于为新闻提要(如 Twitter/Facebook/whatever)存储一系列帖子的最佳方式。为了让事情更简单,让我们考虑一种情况,当您有两种类型的帖子(每种都有不同的单元格 UI):一个“大”帖子(带有照片,文字......)和一个“小”帖子,服务更像通知。如果你想在一个 UI 元素(collectionView / tableView)中显示两种类型的帖子,那么两者都放在一个“posts”数组中很方便,所以我们可以这样做:

    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
    }

如果你这样做,你实际上可以这样做

   var posts : [Post] = [BigPost(), SmallPost(), SmallPost(), BigPost()]

它有效,您只需要使用“postType”var 将每个帖子类型的相应单元格出列。我的问题是,这是一个方法吗?因为我考虑过实现 diffing(witch,例如 deepDiff,这很棒https://github.com/onmyway133/DeepDiff),所以当我们有很多帖子时,collectionView/tableView 中的更新是有效的,但随后,我该怎么做?因为我不能让我的 Post 协议符合其他一些“Diffable”协议,因为那时我不能声明一个 [Post] 类型的数组,即使我同时创建了 smallPost 和 bigPosts,也符合那个“Diffable”协议,我“post”数组中的元素仍然被编译器视为“post”,所以我无法执行任何“diff”。

也许一些具有多态性的策略更好?你觉得呢?你有没有什么想法?

标签: swiftpolymorphismprotocolsdata-modeling

解决方案


看看类型转换 - https://docs.swift.org/swift-book/LanguageGuide/TypeCasting.html

您可以使 smallPost 和 bigPost 符合“Diffable”,创建数组

var posts : [Diffable] = [BigPost(), SmallPost(), SmallPost(), BigPost()]

然后检查它们的类型:

if let post = posts[0] as? SmallPost {
   // do something
}

或者

if let post = posts[0] as? BigPost {
   // do something
}

而且您不需要额外的属性(var postType : PostType {get set})


推荐阅读