IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 移动开发 -> [Swift 开发] Combine使用方法 -> 正文阅读

[移动开发][Swift 开发] Combine使用方法

?这片主要介绍Combine基本用法

?1. Just

    let myPublisher = Just("1")
    
    let myScriber = Subscribers.Sink<String, Never> { completion in
        if completion == .finished {
            print("myScriber1 Finished")
        } else {
            print("myScriber1 Failure")
        }
    } receiveValue: { value in
        print(value)
    }

    myPublisher.subscribe(myScriber)


    打印结果:
    // 1
    // myScriber1 Finished

1. Just发布一个Publisher,just只会发送一次,发送完成结束本次订阅
2. Sink订阅者,订阅了Just,这个Sink后面是个泛型

????????第一参数是参数类型,方法Just发送的是String类型,所以咱们观察者类型要保持一致

??????? 第二参数是错误类型,例子中参数是Never,就是不会报错,下面的例子中会介绍其它的
3.? Sink中有两个闭包 (receiveCompletion和receiveValue)

????????receiveCompletion: 结束观察订阅
????????receiveValue: 订阅结果

extension Publisher { 
    public func sink(receiveCompletion: @escaping ((Subscribers.Completion<Self.Failure>) -> Void), receiveValue: @escaping ((Self.Output) -> Void)) -> AnyCancellable
}

extension Publisher where Self.Failure == Never {
    public func sink(receiveValue: @escaping ((Self.Output) -> Void)) -> AnyCancellable
}

// 如果不需要receiveCompletion,我们可以用Self.Failure == Never方法

2. Publishers

Publishers处于pipline的最上游,它的主要作用是发送数据

    let arr = 0...3
    arr.publisher.sink { value in
        print(value)
    }

    打印结果:
    // 0
    // 1
    // 2
    // 3

Combine给了我们一个简便的写法

适用环境,比如我们在意的是直接拿到结果,不需要中间的Operator
?

3. assign

    class Person {
        var age: Int = 0 {
            didSet {
                print("age: \(age)")
            }
        }
    }
    
    
    let person = Person()
    let range = 0...2
    range.publisher.assign(to: \.age, on: person)

    打印结果:
    // 0
    // 1
    // 2

keyPath

将发布者中的每个元素分配给对象上的属性。

使用Publisher/assign(to:on:)订阅者,当你想在每次发行者产生一个值时设置给定的属性。

在这个例子中,Publisher/assign(to:on:) 在person的实例上设置age属性的值

第二种用法

    class Person {
        @Published var age: Int = 0
    }
    
    
    let person = Person()
    Just(1).assign(to: &person.$age)
    print(person.age) 

    打印结果: 
    // 1

熟悉SwiftUI的朋友看起来比较喜欢,属性包装器的写法

** assign 都是 Self.Failure == Never

4. Future

    class Person {
        var age: Int = 0
    }
    
    let futurePubliser = Future<Int ,Never> { promise in
        print("异步操作")
        promise(.success(2))
        
    }
    
    let subscribers = Subscribers.Sink<Int,Never> { completion in
        if completion == .finished {
            print("Finished")
        } else {
            print("Failure")
        }
    } receiveValue: { value in
        print(value)
    }

    futurePubliser.subscribe(subscribers) 
    
    let person = Person()
    futurePubliser.assign(to: \.age, on: person)

    打印结果:
    // 异步操作
    // 2
    // Finished

Future和Just类似,区别在于:

??????? Just直接发送参数, Failure = Never
??????? Futrre是调用一个异步闭包,可以选择闭包结束时发送数据, Failure = Error

5. Operator

    let myPubliser2 = Just("1")
    
    let tansValue = Publishers.Map<Just<String>, Int>(upstream: myPubliser2) { value in
        return Int(value) ?? 0
    }
    
    let myScriber2 = Subscribers.Sink<Int,Never>  { completion in
        if completion == .finished {
            print("Finished")
        } else {
            print("Failure")
        }
    } receiveValue: { value in
        print(value)
    }

    tansValue.subscribe(myScriber2)

    打印结果:
    // 1
    // Finished

使用提供的闭包转换来自上游发布者的所有元素的发布者

Operator处于pipline的中游,它的主要作用是接收数据,处理数据,再发送数据

此发布者可能发布的错误类型, 此发布者使用其上游发布者的失败类型。

6. Operator2

    _ = Just(1).filter({ value in
        return value < 10
    }).sink(receiveCompletion: { completion in
        if completion == .finished {
            print("Finished")
        } else {
            print("Failure")
        }
    }, receiveValue: { value in
        print(value)
    })

    打印结果:
    // 1
    // Finished
extension Just {
    public func filter(_ isIncluded: (Output) -> Bool) -> Optional<Output>.Publisher
}

注意这个filter,它不是高阶函数里的那个filter,虽然它们功能都是数据过滤。但它属于Just, 它返回的是Publisher

7. CurrentValueSubject? send

    // 定义一个错误类型
    enum myErrors: Error {
        case wrongValue
    }

    // 定义一个publiser
    let publiser = CurrentValueSubject<String, myErrors>("10")
    

    // 第一个接收者
    publiser.filter {
        return $0.count < 2
    }.sink { completion in
        if completion == .failure(myErrors.wrongValue) {
            print("Scriber1 Finished")
        } else {
            print("Scriber1: \(completion)")
        }
    } receiveValue: { value in
        print("Scriber1: \(value)")
    }
    
    // 第二个接收者
    let myScriber = Subscribers.Sink<String,myErrors> { completion in
        if completion == .failure(myErrors.wrongValue) {
            print("Scriber2 Finished")
        } else {
            print("Scriber2: \(completion)")
        }
    } receiveValue: { value in
        print("Scriber2: \(value)")
    }
    
    publiser.subscribe(myScriber)
    
    
    // 开始发送数据
    publiser.send("1")
    publiser.send("11")
    publiser.send(completion: .failure(.wrongValue))
    publiser.send("over")

    打印结果:
    // Scriber2: 10
    // Scriber1: 1
    // Scriber2: 1
    // Scriber2: 11
    // Scriber1 Finished
    // Scriber2 Finished

CurrentValueSubject可以订阅一个publiser, 它可以多点用send发布数据,直到发送completion结束观察

Failure = Error

8. CurrentValueSubject? Operator

    let subject1: CurrentValueSubject<Int,myErrors> = .init(10)
    let subject2: CurrentValueSubject<Int,myErrors> = .init(20)

    // 数据流 subject1 -> subject2
    _ = subject1.subscribe(subject2)

    let myScriber = Subscribers.Sink<Int,myErrors> { completion in
        if completion == .finished {
            print("Finished")
        } else {
            print("Failure")
        }
    } receiveValue: { value in
        print(value)
    }
    
    subject2.receive(subscriber: myScriber)
    
    subject1.send(1)
    subject1.send(2)
    subject2.send(3)
    subject1.send(completion: .failure(.wrongValue))
    subject1.send(11)
    subject2.send(12)

    打印结果:
    // 10
    // 1
    // 2
    // 3
    // Failure

CurrentValueSubject也可以当作Operator适用
例子中subject1处于pipline的上游,subject2处于pipline的中游

Failure = Error

subject1.send(1)????? //? subject1 -> subject2 ->Scriber
subject1.send(2)????? //? subject1 -> subject2 ->Scriber
subject2.send(3)??? ? //? subject2 ->Scriber
subject1.send(completion: .failure(.wrongValue))?? //? 结束myScriber的响应者

9. PassthroughSubject

    let subject1: PassthroughSubject<Int,myErrors> = PassthroughSubject()
    let subject2: PassthroughSubject<Int,myErrors> = PassthroughSubject()

    // 数据流 subject1 -> subject2
    let cancelable = subject1.subscribe(subject2)

    let myScriber = Subscribers.Sink<Int,myErrors> { completion in
        if completion == .finished {
            print("Finished")
        } else {
            print("Failure")
        }
    } receiveValue: { value in
        print(value)
    }
    
    subject2.receive(subscriber: myScriber)
    
    subject1.send(1)
    subject1.send(2)
    subject2.send(3)
    subject1.send(completion: .failure(.wrongValue))
    subject1.send(11)
    subject2.send(12)

    打印结果: 
    // 1
    // 2
    // 3
    // Failure

PassthroughSubject和CurrentValueSubject功能类似

区别在于

????????CurrentValueSubject: 有个初始化值

????????PassthroughSubject:没有初始化值

  移动开发 最新文章
Vue3装载axios和element-ui
android adb cmd
【xcode】Xcode常用快捷键与技巧
Android开发中的线程池使用
Java 和 Android 的 Base64
Android 测试文字编码格式
微信小程序支付
安卓权限记录
知乎之自动养号
【Android Jetpack】DataStore
上一篇文章      下一篇文章      查看所有文章
加:2022-09-21 00:40:22  更:2022-09-21 00:42:11 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/25 4:45:17-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码