flutter的foundation其他小工具

2020-08-22  本文已影响0人  一叠纸船
  1. 在foundation模块下有一个文件是object.dart,这个文件唯一的一个函数就是工具函数objectRuntimeType。
    这个objectRuntimeType是很有意思,也很实用的。它存在最主要的原因是,在一个runtime调用toString会对性能产生负面的影响。所以把它封装了一下放在assert里面执行,巧妙地利用了assert在release模式下不会执行的特点。其中传入的optimizedValue是一个常量,可以是任何字符串,在release模式下,这个函数最后会返回optimizedValue,来保证性能和逻辑的连贯性不受影响。实际代码如下:
String objectRuntimeType(Object object, String optimizedValue) {
  assert(() {
    optimizedValue = object.runtimeType.toString();
    return true;
  }());
  return optimizedValue;
}
  1. foundation模块下有一个文件是collections.dart,这个文件提供了四个集合的工具函数,分别是:setEquals,listEquals,mapEquals,binarySearch。
bool setEquals<T>(Set<T> a, Set<T> b) {
  if (a == null)
    return b == null;
  if (b == null || a.length != b.length)
    return false;
  if (identical(a, b)) //这个就是确定指针(引用)指向的是不是同一块内存地址
    return true;
  for (final T value in a) { //和listEquals及mapEquals相比仅这一块不一样,目的是判断内容是否一致
    if (!b.contains(value))
      return false;
  }
  return true;
}
int binarySearch<T extends Comparable<Object>>(List<T> sortedList, T value) {
  int min = 0;
  int max = sortedList.length;
  while (min < max) {
    final int mid = min + ((max - min) >> 1); //这个方式还是很有新意的,值得借鉴
    final T element = sortedList[mid];
    final int comp = element.compareTo(value);
    if (comp == 0) {
      return mid;
    }
    if (comp < 0) {
      min = mid + 1;
    } else {
      max = mid;
    }
  }
  return -1;
}
  1. foundation模块下有一个文件是constants.dart,这个文件里提供了5个常量。其中最常用到的是kReleaseMode
  1. foundation模块下有一个文件是profile.dart, 这个文件只有一个profile函数。这个函数已经废弃,功能完全可以用上文提到的constants.dart文件里的kReleaseMode替代。

  2. foundation模块下有platform.dart, 里面有三个很有用的东西:

    • 开发项目时,常用到的TargetPlatform枚举:** android,fuchsia, iOS, linux, macOS, windows**.
    • 获取默认的defaultTargetPlatform,这个一般就是当前设备的系统类型,在_platform_io.dart文件里,封装了一个获取defaultTargetPlatform类型的方法。获取设备类型优先使用Theme.of获取,在写更底层的实现无法用Theme.of是,才用这个获取。
    • debugDefaultTargetPlatformOverride这个就是重写defaultTargetPlatform的值,这个属性通常在测试的时候才会用到。
  3. foundation模块下有一个文件是synchronous_future.dart。
    SynchronousFuture是一个class,这个的功能和new Future.value相似,只是他是同步的。这个内部实现代码不多,基本都能看的明白,代码如下:

class SynchronousFuture<T> implements Future<T> {
  SynchronousFuture(this._value);

  final T _value;

  @override
  Stream<T> asStream() {
    final StreamController<T> controller = StreamController<T>();
    controller.add(_value);
    controller.close();
    return controller.stream;
  }

  @override
  Future<T> catchError(Function onError, { bool test(Object error) }) => Completer<T>().future;

  @override
  Future<E> then<E>(FutureOr<E> f(T value), { Function onError }) {
    final dynamic result = f(_value);
    if (result is Future<E>)
      return result;
    return SynchronousFuture<E>(result as E);
  }

  @override
  Future<T> timeout(Duration timeLimit, { FutureOr<T> onTimeout() }) {
    return Future<T>.value(_value).timeout(timeLimit, onTimeout: onTimeout);
  }

  @override
  Future<T> whenComplete(FutureOr<dynamic> action()) {
    try {
      final FutureOr<dynamic> result = action();
      if (result is Future)
        return result.then<T>((dynamic value) => _value);
      return this;
    } catch (e, stack) {
      return Future<T>.error(e, stack);
    }
  }
}

SynchronousFuture是很少有场景用到的,如果必须要用到,要特别注意,因为很不好debug这种双峰行为。我写了一个简单的使用示例:

debugPrint('ssss00000');
SynchronousFuture(4).then((value){
  debugPrint('ssss11111');
}).whenComplete((){
  debugPrint('ssss22222');
}).catchError((error) {
  debugPrint('ssss33333');
});
debugPrint('ssss=====');

输出的结果是:

flutter: ssss00000
flutter: ssss11111
flutter: ssss22222
flutter: ssss=====

从输出的结果上大家应该能更直观的了解了。

这是flutter框架源码分析的其中一篇,因能力有限,有诸多不足之处,还请斧正。

上一篇 下一篇

猜你喜欢

热点阅读