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.