ios - 在使用 `Lock.UnfairLock.lock()` 的同时观察 `UIRefreshControl` 时由于 `Action.isExecuting` 而崩溃

标签 ios reactive-swift

我正在使用 UITableView显示分页列表,我正在使用 UIRefreshControl表示正在发生网络请求。

然而,出于某种原因self.refreshControl.beginRefreshing()/self.refreshControl.endRefreshing()导致 os_unfair_lock_lock(_lock) 崩溃.如果我注释掉这两行,代码就可以正常工作。

以下代码可用于重现该问题:

import UIKit
import ReactiveSwift
import Result

class ViewController: UIViewController {

    @IBOutlet var tableView : UITableView!
    var refreshControl : UIRefreshControl!

    var i : Int = 0
    var action : Action<Int,[String],NoError>!
    var words = [String]()

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.delegate = self
        tableView.dataSource = self

        refreshControl = UIRefreshControl()
        tableView.addSubview(refreshControl)

        action = Action<Int,[String],NoError>{ pageNumber in
            return SignalProducer{ sink,_ in
                let deadlineTime = DispatchTime.now() + .seconds(2)
                DispatchQueue.main.asyncAfter(deadline: deadlineTime) {
                    if pageNumber == 1{
                        sink.send(value: ["Apple","Bananas","Clementines"])
                    }else if pageNumber == 2{
                        sink.send(value: ["Dodo","Eels","French"])
                    }
                    sink.sendCompleted()
                }
            }
        }

        action.values.observeValues { [weak self](moreWords) in
            if self?.words.isEmpty ?? true {
                self?.words = moreWords
            }else{
                self?.words.append(contentsOf: moreWords)
            }
            self?.tableView?.reloadData()
        }

         action.isExecuting.signal.observe(on: UIScheduler()).observeValues { [weak self](loading) in
            if loading{
                self?.refreshControl.beginRefreshing()
            }else{
                self?.refreshControl.endRefreshing()
            }
            print("loading \(loading)")
        }
    }
}

extension ViewController : UITableViewDataSource {

    public func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
        return self.words.count
    }

    public func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
        let identifier = "Whatever"
        var cell = tableView.dequeueReusableCell(withIdentifier: identifier)
        if cell == nil{
            cell = UITableViewCell(style: .default, reuseIdentifier: identifier)
        }
        cell!.textLabel?.text = self.words[indexPath.row]
        return cell!
    }
}

extension ViewController : UITableViewDelegate{
    func scrollViewDidScroll(_ scrollView: UIScrollView) {
        if (((scrollView.contentOffset.y + scrollView.frame.size.height) > scrollView.contentSize.height ) ){
           if !self.action.isExecuting.value {
                i += 1
                self.action.apply(i).start()
            }
        }
    }
}

最佳答案

使用 beginRefreshing & endRefreshing在主线程上为:

QueueScheduler.main {
    if loading {
        self?.refreshControl.beginRefreshing()
    } else {
        self?.refreshControl.endRefreshing()
    }
}

关于ios - 在使用 `Lock.UnfairLock.lock()` 的同时观察 `UIRefreshControl` 时由于 `Action.isExecuting` 而崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47986400/

相关文章:

ios - NSString 获取字符串中间的字符串

ios - 在 iOS 中,如何将 JSON 字符串解析为对象

swift - 使用 Combine 合并先前的值

swift - 使用 Reactive Swift 将 View 模型与 View 绑定(bind)

ios - Xcode Swift - 按下按钮时应用程序崩溃

ios - 允许 MasterDetail 页面将主页面放在 Xamarin.forms 的右侧

ios - 希望快速将用户输入发送到网络服务器并加载结果

ios - 自 Xcode 8.3 更新以来,ReactiveCocoa 错误 "Let ' 值'是私有(private)的,无法从 '@inline(__always)' 函数引用

ios - 类型 'UIButton' 的值没有成员 'reactive'

swift - 如何使用 ReactiveCocoa 在 Swift 中观察属性的变化