简体   繁体   中英

Swift - UITableView doesn't work with delegates

The problem is that UITableView.dataSource works fine with extensions, but does not work with delegates. I created new project and added just one UITableView to the storyboard.

Here is the code using extension:

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self
//        tableView.dataSource = Delegate()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

extension ViewController: UITableViewDataSource {
//class Delegate: NSObject, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print(1) // called several times
        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        print(2) // called

        var cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell")
        if cell == nil {
            cell = UITableViewCell(style: .default, reuseIdentifier: "UITableViewCell")
        }
        return cell!
    }
}

Using delegate:

import UIKit

class ViewController: UIViewController {
    @IBOutlet weak var tableView: UITableView!

    override func viewDidLoad() {
        super.viewDidLoad()
//        tableView.dataSource = self
        tableView.dataSource = Delegate()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

//extension ViewController: UITableViewDataSource {
class Delegate: NSObject, UITableViewDataSource {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        print(1) // called several times
        return 1
    }

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        print(2) // doesn't called

        var cell = tableView.dequeueReusableCell(withIdentifier: "UITableViewCell")
        if cell == nil {
            cell = UITableViewCell(style: .default, reuseIdentifier: "UITableViewCell")
        }
        return cell!
    }
}

Has anyone encountered such a problem?

You need to store your Delegate object in you view controller. The reason for this is that dataSource variable of UITableView is a weak variable (so as to prevent retain cycles) - it means that if it isn't stored somewhere in a strong variable, it will immediately get deallocated.

tableView.dataSource = Delegate()

Here you assign new instance of Delegate to a weak variable and nowhere else. Do something like this

class ViewController: UIViewController {
    var delegate = Delegate()

    override func viewDidLoad() {
        super.viewDidLoad()
        tableView.dataSource = self.delegate
}

The dataSource and delegate are both weak . So your Delegate() object with no strong reference will be released after viewDidLoad() .

If you want to use delegate this way, just var delegate: Delegate! in your ViewController . Then in the viewDidLoad() :

self.delegate = Delegate()
tableView.delegate = self.delegate

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM