iOS跨界面或无关联界面传参的探究
2022-07-24 本文已影响0人
迷路的小小
- 使用闭包传参
闭包传参的优点显而易见:低重复性、高可交互性。如下
@dynamicCallable
public struct ParamFactory: CustomStringConvertible {
public var closure: (KeyValuePairs<String, Any>) -> Any
public init(_ closure: @escaping (KeyValuePairs<String, Any>) -> Any) {
self.closure = closure
}
@discardableResult
public func dynamicallyCall(withKeywordArguments args: KeyValuePairs<String, Any>) -> Any {
return closure(args)
}
}
结合dynamicCallable
特性,产生无固定参数的效果,实现双端交互。
- 原数据持有者持有闭包
public typealias ParamDictionary = Dictionary<String, ParamFactory>
class ViewController: BaseViewController {
var dic = ParamDictionary()
}
这样做的好处是最大限度的节省资源,在不需要的时候确保释放。
- 为了方便逻辑处理且达到无阻碍使用的效果,采用属性包装器
propertyWrapper
- 为了能够跨区使用,采用单例模式。
单例:
internal final class Transmitter {
static let share = Transmitter()
var queue = [WeakParamPublisher]()
static func awaken(param: ParamPublisher) {
update(param: param)
}
static func update(param: ParamPublisher) {
share.update(param: param)
}
func update(param: ParamPublisher) {
let weakPublisher = WeakParamPublisher(publisher: param)
if let i = queue.firstIndex(of: weakPublisher) {
queue.swapAt(i, queue.count - 1)
} else {
queue.append(weakPublisher)
}
}
subscript(key: String) -> ParamFactory! {
let transitives = queue.compactMap({ $0.publisher?.wrappedValue })
return transitives.compactMap({ $0[key] }).last
}
subscript(keys: String...) -> [ParamFactory?] {
return keys.map({ self[$0] })
}
subscript(keys: [String]) -> [ParamFactory?] {
return keys.map({ self[$0] })
}
}
使用属性包装器:
@propertyWrapper
@dynamicMemberLookup
public final class ParamPublisher: Hashable, CustomStringConvertible {
public var wrappedValue: ParamDictionary {
get { value }
set {
value = newValue
Transmitter.awaken(param: self)
}
}
private var value: ParamDictionary
public var description: String { String(describing: value) }
public init(wrappedValue: ParamDictionary = .init()) {
self.value = wrappedValue
Transmitter.update(param: self)
}
deinit {
Transmitter.share.queue.removeAll { [weak self] in $0.publisher == self }
}
public subscript(dynamicMember member: String) -> ((KeyValuePairs<String, Any>) -> Any)! {
get { value[closure: member] }
set { value[closure: member] = newValue }
}
public func hash(into hasher: inout Hasher) {
let opaque = Unmanaged.passUnretained(self).toOpaque()
hasher.combine("\(opaque)")
}
public static func == (lhs: ParamPublisher, rhs: ParamPublisher) -> Bool {
lhs.hashValue == rhs.hashValue
}
}
继而实现参数发布和参数提取的隔离,实现跨区域传参。
代码地址