【问题标题】:Whats the best practice for object pool pattern in flutter/dart?颤振/飞镖中对象池模式的最佳实践是什么?
【发布时间】:2021-09-27 03:57:33
【问题描述】:

想象一个非常简单的应用程序,它有两个页面,PostListPostDetail。在前一页上,我们显示 posts 的列表,在后一页上,显示单个 post 的详细信息。

现在考虑以下情况。我们的用户点击第一个 PostItem 并导航到 PostDetail 页面。我们从服务器获取完整的 post 数据。此 postlikes_count 增加 1。现在,如果我们的用户导航回第一页,PostItem 应该会更新并显示新的 likes_count

一种可能的解决方案是创建一个帖子池。现在,当我们从服务器获取一些新数据时,我们可以更新相应的池实例对象,而不是创建新的 post 对象。例如,如果我们导航到 id=3 的帖子,我们可以这样做:

Post oldPost = PostPool.get(3)
oldPost.updateFromJson(servers_new_json_for_post_3)

由于PostDetail页面上使用了相同的对象,我们在PostList页面上的PostItem也会随之更新。

在整个应用程序中不使用 Post 对象的唯一“单个实例”的其他方法实施起来并不干净,并且需要一些技巧来保持 UI 同步。

但 ObjectPool 方法也有其自身的问题,并且会导致内存泄漏,因为池的大小会随着时间的推移变得越来越大。为了解决这个问题,我们需要手动计算每个池对象实例的引用数,并在该计数为零时丢弃它们。这种手动计算充满了错误,我想知道是否有更好的方法来实现这一点。

【问题讨论】:

    标签: flutter dart flutter-provider object-pooling flutter-state


    【解决方案1】:

    您也可以使用 streamsStreamBuilders 来解决此问题。首先,您创建 并使用从 API 获取的初始数据填充它: 我喜欢使用rxdart 中的BehaviorSubject,但您也可以使用普通流。

    final BehaviorSubject<List<Post>> postsStream = BehaviorSubject<List<Post>>()..startWith(<Post>[]);
    

    在构造函数主体或initState 函数中,您将获取数据并将其添加到流中。

    PostPage() {
      _fetchPosts().then((posts) => postsStream.add(posts));
    }
    

    您现在可以使用StreamBuilder 在两个页面中订阅此postsStream 的更改。您需要执行的任何更新都将向流发送一个新的(更新的List&lt;Post&gt;,从而在订阅了具有新值和更新值的流的任何StreamBuilder 上触发重建。

    您可以稍后处理 StreamController。

    【讨论】:

    • 嗨佩德罗,非常感谢您的详尽回答。是的,我熟悉这个概念,我知道您的方法实际上会导致同步 UI。但我的问题仍然存在。我想在整个应用程序中拥有一个 Post 对象(对于每个 post_id)。当然,还有一种解决上述内存泄漏问题的方法。
    • 嗨@EmadHedayati,很抱歉不能为您提供更多帮助。我不熟悉这个 ObjectPool 模式,但它让我很感兴趣。希望您尽快找到更合适的解决方案并告诉我们。
    • 没问题!您的回答实际上很有用,我从中学到了一些新东西。
    猜你喜欢
    • 2019-02-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-25
    • 2021-02-09
    • 1970-01-01
    • 2021-09-09
    • 2022-11-09
    相关资源
    最近更新 更多