借助PropertyWrapper自动创建/销毁那些开销较大的Formatter

182 阅读1分钟

最近项目中涉及到格式化数字的功能,因为NumberFormatter的开销比较大(DateFormatter也是),所以用泛型和PropertyWrapper来处理NumberFormatter经过一段时间后自动销毁的功能。请大家多多指正。直接上代码:

@propertyWrapper
final class Temporary<T> {
	
	typealias ValueBuilder = () -> T
	
	private var value: T?
	private lazy var timer = GCDTimer.scheduledTimer(
		delay: .now() + survivalTime,
		queue: .global(qos: .background)
	) { _ in
		self.value = .none
	}
	private let survivalTime: TimeInterval
	private let builder: ValueBuilder
	init(wrappedValue: @escaping ValueBuilder, expireIn survivalTime: TimeInterval) {
		self.builder = wrappedValue
		self.survivalTime = survivalTime
	}
	var wrappedValue: T {
		defer {
			// 每次调用都推迟执行
			timer.fire(.now() + survivalTime)
		}
		guard let unwrapped = value else {
			value = builder()
			return value.unsafelyUnwrapped
		}
		return unwrapped
	}
}

然后extension中就可以这么用:

extension Double {
	
	@Temporary<NumberFormatter>(expireIn: .seconds(300))
	fileprivate static var sharedNumberFormatter = NumberFormatter.init
        
        var f2: String? {
		let number = NSNumber(value: self)
		return Self.sharedNumberFormatter.string(from: number)
	}
}