Dart中单例构造函数传入不同参数时如何重建实例?
实现方案
你原来的实现是全局固定唯一实例,要实现传入不同参数新建实例、支持销毁旧实例的需求,改用参数作为Key的缓存Map来管理实例即可,修改后代码如下:
import 'package:flutter/foundation.dart'; class Foo extends ChangeNotifier { // 改为final避免实例的channel被意外修改 final String channel; void instanceMemberFunction () { print('Foo created with channel $channel'); } // 用Map缓存不同channel对应的实例 static final Map<String, Foo> _instanceCache = {}; // 私有构造方法,初始化时直接传入channel Foo._internal({required this.channel}) { instanceMemberFunction(); } factory Foo({required String channel}) { // 对应channel的实例已存在,直接返回缓存 if (_instanceCache.containsKey(channel)) { return _instanceCache[channel]!; } // 不存在则新建实例存入缓存后返回 final newInstance = Foo._internal(channel: channel); _instanceCache[channel] = newInstance; return newInstance; } // 销毁指定channel对应的实例 static void disposeInstance(String channel) { if (_instanceCache.containsKey(channel)) { // 先执行ChangeNotifier的资源清理逻辑 _instanceCache[channel]?.dispose(); _instanceCache.remove(channel); } } // 可选:销毁所有缓存的实例 static void disposeAll() { _instanceCache.forEach((_, instance) => instance.dispose()); _instanceCache.clear(); } }
使用示例
// 首次调用bar参数,新建实例 final foo1 = Foo(channel: "bar"); // 再次调用相同bar参数,返回已有实例 final foo2 = Foo(channel: "bar"); print(foo1 == foo2); // 输出 true // 调用不同baz参数,新建实例 final foo3 = Foo(channel: "baz"); print(foo1 == foo3); // 输出 false // 销毁bar参数对应的旧实例 Foo.disposeInstance("bar"); // 销毁后再次调用bar参数,会创建新的实例 final foo4 = Foo(channel: "bar"); print(foo1 == foo4); // 输出 false
注意事项
- 如果你的区分依据不止channel一个参数,可以把多个参数封装成一个自定义对象作为Map的Key,只要保证相同参数的Key相等即可。
- 从缓存中移除的实例没有其他地方引用时,Dart的垃圾回收会自动回收其占用的内存。
内容的提问来源于stack exchange,提问作者Aditya Sharma
相关产品推荐
相关产品推荐

