美文网首页
全局数据同步(二)UI篇

全局数据同步(二)UI篇

作者: 码农苍耳 | 来源:发表于2017-04-09 18:16 被阅读30次

上次讨论了如何让数据全局同步,但是在同步到UI层的时候还是有些麻烦。现在来解决UI层的问题。

之前的方案有两种:

  1. 在viewWillAppear的时候,reloadData,缺点是如果需要reload的数据太多,大量计算会导致阻塞主线程,虽然可能没有那么严重,但是有些时候还是能够感知出来。
  2. 使用KVO来监听变化,缺点是代码侵入性太强,而且严重影响了一些代码的统一性。

下面是使用KVO的一个例子:

@weakify(self);
[self.KVOController observe:_record keyPath:NSStringFromSelector(@selector(praiseCount)) options:NSKeyValueObservingOptionNew block:^(id  _Nullable observer, MZRecord *object, NSDictionary<NSString *,id> * _Nonnull change) {
      @strongify(self);
      self.recordTabbar.praiseCount = object.praiseCount;
}];
[self.KVOController observe:_record keyPath:NSStringFromSelector(@selector(praised)) options:NSKeyValueObservingOptionNew block:^(id  _Nullable observer, MZRecord *object, NSDictionary<NSString *,id> * _Nonnull change) {
     @strongify(self);
     [self.recordTabbar setPraised:object.isPraised animated:self.view.window != nil];
}];
[self.KVOController observe:_record keyPath:NSStringFromSelector(@selector(collected)) options:NSKeyValueObservingOptionNew block:^(id  _Nullable observer, MZRecord *object, NSDictionary<NSString *,id> * _Nonnull change) {
    @strongify(self);
    [self.recordTabbar setCollected:object.collected animated:self.view.window != nil];
}];
[self.KVOController observe:_record keyPath:NSStringFromSelector(@selector(collectCount)) options:NSKeyValueObservingOptionNew block:^(id  _Nullable observer, MZRecord *object, NSDictionary<NSString *,id> * _Nonnull change) {
    @strongify(self);
    self.recordTabbar.collectCount = object.collectCount;
}];
[self.KVOController observe:_record keyPath:NSStringFromSelector(@selector(commentCount)) options:NSKeyValueObservingOptionNew block:^(id  _Nullable observer, MZRecord *object, NSDictionary<NSString *,id> * _Nonnull change) {
    @strongify(self);
    self.recordTabbar.commentCount = object.commentCount;
}];

上面是我们为了同步3个按钮的状态的代码,我们使用了一个第三方库来简化KVO的编写,但还是非常的冗余。

为此,开始思考有什么更简单的方法。

开始我们想要封装KVO,直接绑定数据和UI,但是很多数据并不是一一对应的,比如数字,状态,是需要转化的,而且状态变更很多情况下是需要动效的,所以无论如何都不免不了监听和转换这两个东西。

后来想,既然数据可以做全局同步,那么是否可以把视图也看作一种类型的资源,也自动同步该状态属性呢?按照这种思路,将视图改写支持这种方式来同步。

@interface UIView (MZChannel) <MZChannelProtocol>
// 我们需要在创建的时候就确定类型,而且不能修改,防止意料之外的情况
- (instancetype)initWithFrame:(CGRect)frame channelType:(NSInteger)channelType;
// 加入数据池中,并且内部增加了lock,保证线程安全
- (void)bindId:(NSString *)id;
// 为了避免与view自身属性冲突,增加了一个白名单配置
- (NSArray<NSString *> *)channelWhiteList;
@end

查看一下我们修改之后的状态

// RecordTabbar
// 新增这两个方法,由于之前设计中的接口与该keyPath统一,所以其他内容不需要修改
- (NSInteger)channelType {
    return MZResourceTypeNote;
}

- (NSArray<NSString *> *)channelWhiteList {
    return @[NSStringFromSelector(@selector(praised)),
             NSStringFromSelector(@selector(praiseCount)),
             NSStringFromSelector(@selector(collected)),
             NSStringFromSelector(@selector(collectCount)),
             NSStringFromSelector(@selector(commentCount))];
}
// 部分对应的setter方法
- (void)setPraised:(BOOL)praised {
    _praised = praised;
    [self.praiseButton setPraised:praised animated:self.window != nil];
}

- (void)setPraised:(BOOL)praised animated:(BOOL)animated {
    _praised = praised;
    [self.praiseButton setPraised:praised animated:animated];
}

- (void)setPraiseCount:(NSInteger)praiseCount {
    _praiseCount = praiseCount;
    self.praiseButton.praiseCount = praiseCount;
}

- (void)setCollected:(BOOL)collected {
    [self setCollected:collected animated:self.window != nil];
}

由于该页面资源id并不会变化,所以只需要在初始化的时候绑定一次id就可以了。

[self.recordTabbar bindId:self.record.id];

这样我们的后半部分流程(从数据到显示)也完整了,整个流程都依赖于MZChannel进行。

相关文章

  • 全局数据同步(二)UI篇

    上次讨论了如何让数据全局同步,但是在同步到UI层的时候还是有些麻烦。现在来解决UI层的问题。 之前的方案有两种: ...

  • 面试UI相关

    UI相关 1. UI视图数据源同步 并发访问,数据同步 (内存消耗 ) 串行访问(子线程耗时,会有延时) 2. 事...

  • 全局数据同步(三)终极方案

    在全局数据同步系列文章中(一)(二)分别解决了model和view的全局同步,但是依然有一些问题,所以在这里给一个...

  • UI视图相关问题

    UI视图相关点 一.UITableView的重用机制 二.数据源同步问题(增删改查) 1.并发访问、数据拷贝(删除...

  • UI主要技术

    UITableView重用机制 数据源同步问题例如:ui显示数据源请求来的数据,删除某行后,子线程请求数据又同步到...

  • @State @Binding

    @State 和 RN 的一样, 就是 UI 和 数据的同步, 当值改变的时候 UI 同时改变 @Binding ...

  • Feed流组件开发中出现的问题

    出现的问题: 1. 数据与界面的同步,业务逻辑与界面显示的划分 数据变化时,需要更新UI。UI的更新要根据当前数...

  • 移动端同步方案

    飞地有用户写作的需求,所以积累了写作和数据同步的技术研究,这是第二篇数据同步,第一篇写作点此进入。 因为产品有草稿...

  • 笔记

    一、UI视图相关 1、UITableView数据源同步 (1)并发访问,数据拷贝例如:在列表删除一个cell数据,...

  • UI数据源同步

    数据源同步问题多线程对共享数据的访问,需要考虑数据源的同步问题,如何解决tableView在多线程环境下的修改或者...

网友评论

      本文标题:全局数据同步(二)UI篇

      本文链接:https://www.haomeiwen.com/subject/jkadattx.html