refreshControl中的完成处理程序具有EXC_BAD_ACCESS错误

时间:2017-07-20 02:32:11

标签: ios swift uitableview swift3 uirefreshcontrol

我使用Firebase作为我的数据结构。我在UITableView的refreshControl中使用了完成处理程序,以便在完成从Firebase加载所有数据后停止刷新。

override func viewDidLoad() {
    super.viewDidLoad()
    self.refreshControl = UIRefreshControl()
    self.refreshControl!.addTarget(self, action: #selector(refreshData),for: .valueChanged)
    self.refreshControl!.attributedTitle = NSAttributedString(string: "Update the data")
    refreshData{ _ in
        self.refreshControl!.endRefreshing()
    }
}

这是我的refreshData方法

func refreshData(completionHandler:@escaping (Bool)->() ) {
    //Remove old data
    self.items.removeAll()
    //Renew all data
    var ref: DatabaseReference!
    ref = Database.database().reference(withPath: "tasks")
    //Loading local drafts
    var drafts : [Task]!
    if let local_drafts = NSKeyedUnarchiver.unarchiveObject(withFile: Task.ArchiveURL.path) as? [Task] {
        drafts = local_drafts
    }
    else{
        drafts = []
    }
    //Reloading the database
    ref.observe(.value, with: { snapshot in
        var newItems: [Task] = []
        self.num_of_tasks = Int(snapshot.childrenCount)
        for item in snapshot.children {
            //let local = item as! DataSnapshot
            //let snapshotValue = local.value as! [String: AnyObject]
            //print(snapshotValue["main_content"] as! String!)
            let taskItem = Task(snapshot: item as! DataSnapshot)
            newItems.append(taskItem!)
        }
        let merged = drafts + newItems
        self.items = merged
        completionHandler(true) //THIS LINE HAS ERR_BAD_ACCESS
    })
}

我认为问题可能是viewDidLoad中的两个refreshData。但我不知道如何解决它。我怎么能用handler作为选择器添加refreshData?

1 个答案:

答案 0 :(得分:1)

这不是线程问题。我通过将函数调用包装在另一个函数中来解决它,因为在这一行中

self.refreshControl!.addTarget(self, action: #selector(refreshData),for: .valueChanged)

我尝试使用refreshData作为选择器,但实际上,选择器本身没有任何完成处理程序,因此每当用户尝试通过向下拖动场景来更新时都会导致内存错误。所以通过将函数调用包装在另一个函数中

 func refresh(){
        refreshData{ [weak self] _ in
            if let _ = self {
                self?.refreshControl!.endRefreshing()
            }
        }
    }

并在选择器中使用此函数,它将提供正确的完成处理程序,从而解决问题。