aiQG's Blog

Happy hacking. Happy developing.

aiQG's GitHub ⛓Links P
Other CTF Swift Developing&Reversing

Combine of swift

20 April 2020

by aiQG_

Using Combine

操作符类符合Subscriber协议和Publisher协议

可以拆分/合并数据流

A simple Combine pipeline written in swift might look like:


let _ = Just(5)    // 输出类型为<Integer>, 失败类型为<Never>
    .map { value -> String in
        // do something with the incoming value here
        // and return a string
        return "a string"
    }              // 输出类型为<String>, 失败类型为<Never>
    .sink { receivedValue in
        // sink is the subscriber and terminates the pipeline
        print("The end result was \(receivedValue)")
    }              // sink用来结束

SwiftUI使用Combine提供的@Published和@ObservedObject属性包装器隐式创建发布者

一个简单的例子

import UIKit
import Combine

class ViewController: UIViewController {
	
	@IBOutlet weak var textLabel: UILabel!
	@IBOutlet weak var actionButton: UIButton!
	
	@Published var labelValue: String? = "Click the button!"
	
	var cancellable: AnyCancellable?
	
	override func viewDidLoad() {
		super.viewDidLoad()
		
		self.cancellable = self.$labelValue.receive(on: DispatchQueue.main)
			.assign(to: \.text, on: self.textLabel)
		
	}
	
	@IBAction func actionButtonTouched(_ sender: UIButton) {
		self.labelValue = "Hello World!"
	}
}

通过使用 $assign 函数, 可以创建绑定并订阅值的修改.

如果 labelValue 被改变, 则 self.textLabeltext 也会被修改. (UI会被更新)

// 因为这是更新UI的功能, 所以在主队列上进行. ( receive 指定)

$ 可以访问被(@Published)包装的值

Introducing Combine

Combine in Practice

  同步 异步
单个值 Int Future
多个值 Array Publisher

上游到下游的传递, 会在遇到错误/结束时终止

Operators⬇️: 介于Subscribers与Publishers之间(充当数据处理的角色)

Zip: 可以将多个上游的值转换为单个元组, 发至下游

CombineLatest: 若上游其中一个值改变, 则重新组合成一个元组发至下游

debounce: 间隔一段时间向下游传递值

removeDuplicates: 删除重复的值(这次从上游传下来的值与上次的相同, 则不再向下游传递)

assign: 将发布者传递的值应用于由keypath定义的对象上

.assign(to: \.isEnabled, on: aButton)

sink: 接收一个任何类型的闭包, 并终止到下游的传输(debug很有用)

catch: 可以提供一个闭包. 在收到上游的错误后: 1). 停止上游的连接. 2). 将闭包作为上游(Publisher), 开始接收闭包的值 (可以替换原来的Publisher)(闭包return一个Publisher(Just))

可以利用flatMap防止与上游的连结断开:


//******
.map{****}
.flatMap{ data in
    return Just(data)
    .decode(***.self, JSONDecoder())//这里可能会产生错误
    .catch{
        return Just(***.NoError)//这里一定不产生错误
    }
}

// 放在flatMap内部, 不影响外部与上游的连接

// 还有各种高阶函数

tryMap: 相比map(不改变并继续传递失败类型,)可以抛出错误. 可以提供一个出错时调用的闭包.

Just(5)
.tryMap {
    if inValue < 5 { 
        throw MyFailure.notBigEnough 
    }
    return inValue 
}
Developing&Reversing

return

email:nrxxmzlrovqw4z3fgeztcncaozuxaltroexgg33n

桂ICP备18011144号-1 (点击访问安全的工信部网站)