美文网首页RxSwift干货Swift学习
RxSwift 入门练习总结

RxSwift 入门练习总结

作者: 船长_ | 来源:发表于2017-08-24 12:55 被阅读293次
    demo.gif

    使用的第三方库

    target 'WeatherDemo_RxSwift' do
    
      use_frameworks!
    
      pod 'RxSwift', '~> 3.5.0'
      pod 'RxCocoa', '~> 3.5.0'
      pod 'RxDataSources', '~> 1.0.4'
      
    end
    

    1.所有的控制器都加上析构函数,以方便查看是否有循环引用

    deinit {
            print("\(self) 释放")
     }
    

    2.按钮订阅点击事件

    tapButton.rx.tap
                .subscribe({ [unowned self] _ in
                    let numStr : String = self.numberLabel.text!
                    let number = Int(numStr)
                    self.numberLabel.text = String(number! + 1)
                
                }).addDisposableTo(disposeBag)
    

    注意: 一定要加[unowned self],或者[weak self]否则会出现循环引用,关于它俩的使用情况,参考@ONEVCAT内存管理,WEAK 和 UNOWNED

    3.订阅手势事件,给按钮添加长按手势

    let longPressGesture = UILongPressGestureRecognizer()
    longPressGesture.rx.event
                .subscribe(onNext: { [unowned self] _ in
                
                    let numStr : String = self.numberLabel.text!
                    let number = Int(numStr)
                    self.numberLabel.text = String(number! + 1)
                    
                }).addDisposableTo(disposeBag)
    self.tapButton.addGestureRecognizer(longPressGesture)
    

    此处,用了subscribe.onNext.注意:onNext 只监听sequence发出的next事件中的element进行处理,他会忽略error和completed事件

    疑问点:大部分情况subscribe 硬敲出来的 为啥代码没有自动补全???

    4.结合tableView,Variable使用示例

    // Variable流,初始值字符串数组
    let items = Variable(["Mike",
                        "Apples",
                        "Ham",
                        "Eggs"])
    
    let items2 = [
                "Fish",
                "Carrots",
                "Mike",
                "Apples",
                "Ham",
                "Eggs",
                "Bread",
                "Chiken",
                "Water"
            ]
    
    // Variable使用必须要加asObservable
    // 数据流绑定到tableView 
    items.asObservable()
                .bind(to: tableView.rx.items(cellIdentifier: "Cell",cellType:UITableViewCell.self),curriedArgument: { (row, element, cell) in
                    cell.textLabel?.text = element
                }).addDisposableTo(disposeBag)
    
    // 原生的refresh
    refreshControl.rx.controlEvent(.valueChanged)
            .subscribe(onNext: { [unowned self] _ in
              // 更改Variable.value 模拟刷新
                items.value = items2
                self.refreshControl.endRefreshing()
            }).addDisposableTo(disposeBag)
            
    tableView.addSubview(refreshControl)
    
    知识点:
    • 要理解Variable,需要先理解Subject,Subjet是observable和Observer之间的桥梁,一个Subject既是一个Obserable也是一个Observer,他既可以发出事件,也可以监听事件
    • BehaviorSubject : 当你订阅了BehaviorSubject,你会接受到订阅之前的最后一个事件
    • Variable是BehaviorSubject一个包装箱,就像是一个箱子一样,使用的时候需要调用asObservable()拆箱,里面的value是一个BehaviorSubject,他不会发出error事件,但是会自动发出completed事件

    5.逆向传值,代理使用示例

    // 代理声明 必须要继承 class 否则报错
    protocol DataEnteredDelegate: class {
        func userDidEnterInformation( info: String )
    }
    
    // 代理声明必须要weak,防止循环引用
    weak var delegate : DataEnteredDelegate? = nil
    
    // 监听键盘右下角done事件,调用代理方法
    @IBAction func textOnExit(_ sender: Any) {
        delegate?.userDidEnterInformation(info: textField.text!)
        self.navigationController?.popViewController(animated: true)
    }
    
    知识点:
    • 需要把protocol 限制在 class 内,这是因为 Swift 的 protocol 是可以被除了 class 以外的其他类型遵守的, 而对于像 struct 或是 enum 这样的类型,本身就不通过引用计数来管理内存,所以也不可能用 weak 这样的 ARC 的概念来进行修饰
      王巍 (@ONEVCAT) delegate

    6. 第三方RxDataSources使用示例

    // 1.数据流 just用法
    let items = Observable.just([
            SectionModel(model: "B",items:[
                "Barbara Cole",
                "Barbara Cooper",
                "Barbara Diaz",
                "Barbara Edwards",
                "Barbara Garcia",
                "Barbara Gray",
                "Barbara Griffin",
                "Barbara Hill",
                "Barbara Howard",
                "Barbara Hughes"
                ]),
            SectionModel(model:"C",items:[
                "Carol Lopez", "Carol Lopez"
                ]),
            SectionModel(model: "E", items: [
                "Elizabeth Jenkins", "Elizabeth Kelly"
                ]),
            SectionModel(model: "H", items: ["Helen Anderson", "Helen Bailey", "Helen Cole", "Helen Cox"]),
            SectionModel(model: "J", items: ["James Anderson", "James Barnes", "James Bell"]),
            SectionModel(model: "K", items: ["Karen Green", "Karen Jenkins", "Karen Jones", "Karen Jordan"]),
            SectionModel(model: "L", items: ["Linda Taylor", "Linda Taylor", "Linda Torres", "Linda West", "Lisa Brooks"]),
            SectionModel(model: "M", items: ["Margaret Bell", "Margaret Coleman", "Margaret Cox", "Margaret Foster"]),
            SectionModel(model: "R", items: ["Robert Clark", "Robert Coleman", "Robert Cook", "Robert Cook"]),
            SectionModel(model: "S", items: ["Susan Fisher", "Susan Ford", "Susan Ford", "Susan Hernandez", "Susan Howard"]),
            ])
    
    // 2.创建数据源 类型<String,String>
    let dataSource = RxTableViewSectionedReloadDataSource<SectionModel<String,String>>()
    
    // 3. dataSources配置cell
    fileprivate func setupDataSource() {
            
            // 参数必须4个,_占位用
            dataSource.configureCell =  { (_,tableView,IndexPath,element) in
                let cell = tableView.dequeueReusableCell(withIdentifier: "Cell")!
                cell.textLabel?.text = element
                return cell
            }
            
            // 监听右侧边缘小字母点击事件
            dataSource.sectionForSectionIndexTitle = { (dataSource,title,index) -> Int in
                print("\(index)")
                return index
            }
            
            dataSource.sectionIndexTitles = { data -> [String]? in
                return data.sectionModels.map{ $0.model }
            }
        }
    
    //  4. 数据流items,绑定到dataSource上
     items.bind(to: tableView.rx.items(dataSource: dataSource))
    
    // 5. 设置tableView代理
     _ = tableView.rx.setDelegate(self)
    

    7. 自定义可观察序列create 示例

    //  create 自定义可观察序列 返回的WeatherData 类型流
         func fetchWeatherData() -> Observable<WeatherData> {
            let observable = Observable<WeatherData>.create { [weak self] observer in
                if let weakSelf = self{
                    let time = 0.5 + TimeInterval(arc4random_uniform(10)) / 10.0
                    
                    // 主线程延迟处理,模拟网络请求数据
                    DispatchQueue.main.asyncAfter(deadline: .now() + time, execute: { 
                        let shouldFail = arc4random_uniform(2) == 0
                        if shouldFail {
                            observer.onError(NSError(domain:"Fake network error", code: 0, userInfo: nil))
                        }else{
                            observer.onNext(weakSelf.createRandomWeatherData())
                            observer.onCompleted()
                        }
                        
                    })
                }
                return Disposables.create() // 固定写法,记住 需实现.onError() .onNext .onCompleted
            }
            return observable.shareReplay(1)
        }
    
    // 建议使用addDisposableTo
    self.viewModel.locationName.drive(self.locationLabel.rx.text).addDisposableTo(disposeBag)
    
    // 而不是用 disposed(by: disposeBag)
    self.viewModel.locationName.drive(self.locationLabel.rx.text).disposed(by: disposeBag)
    
    // 按钮tap事件建议使用subscribe
    button.rx.tap
                .subscribe(onNext:{
                    [unowned self] in
                    let selectedDate = dateFormatter.string(from: self.datePicker.date)
                    self.title = selectedDate
                }).addDisposableTo(disposeBag)
    
    // 而不是用bind
    button.rx.tap
                .bind { [unowned self] in
                    let selectedDate = dateFormatter.string(from: self.datePicker.date)
                    self.title = selectedDate
            }.addDisposableTo(disposeBag)
    
    

    RxSwift概念理解
    RxSwift学习资料,内涵很多RxSwift开源项目
    本示例下载

    相关文章

      网友评论

        本文标题:RxSwift 入门练习总结

        本文链接:https://www.haomeiwen.com/subject/gzvsdxtx.html