如何禁用 Tableview DequeueReusableCell?
How to disable Tableview DequeueReusableCell?
我试图在不使用 dequeueReusableCell 的情况下加载我的 tableview,但它只是让我的应用程序崩溃,无法弄清楚我做错了什么?
let cell = Tableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SökrutaCell // THIS CODE WORKS FINE
let cell = SökrutaCell() // THIS CODE CRASHES - Unexpectedly found nil while unwrapping an optional
如果有人能指出我正确的方向,我会很高兴,这样我就能理解失败的原因。
import UIKit
import Alamofire
class Sökruta: UIViewController {
var sökresultat = [Object2]()
@IBOutlet weak var Tableview: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
GetRequest(Url: "https://randomurl.se")
Tableview.delegate = self
Tableview.dataSource = self
Tableview.backgroundColor = UIColor.white
// Do any additional setup after loading the view.
}
}
// MARK: - Delegate extension 1
extension Sökruta: UITableViewDelegate{
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("you tapped me!")
}
}
// MARK: - Delegate extension 2
extension Sökruta: UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sökresultat.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// let cell = Tableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SökrutaCell // THIS CODE WORKS FINE
let cell = SökrutaCell() // THIS CODE CRASHES - Unexpectedly found nil while unwrapping an optional
cell.Söknamn.text = sökresultat[indexPath.row].displayname
if let url = URL(string: dontmindthiscode) {
DispatchQueue.global().async {
do {
let data = try Data(contentsOf: url)
DispatchQueue.main.async {
cell.Sökbild.image = UIImage(data: data)
}
} catch let err {
print("error: \(err.localizedDescription)")
}
}
}
else
{
DispatchQueue.main.async {
cell.Sökbild.image = UIImage(systemName: "eye.slash")
}
}
return cell
}
}
// MARK: - Extension functions
extension Sökruta{
// MARK: - GET REQUEST
func GetRequest(Url: String) {
// MARK: - Login details
let headers: HTTPHeaders = [
.authorization(username: "username", password: "password"),
.accept("application/json")]
// MARK: - Api request
AF.request(result, headers: headers).validate().responseJSON { response in
// MARK: - Check for errors
if let error = response.error
{
print (error)
return}
// MARK: - Print response
if response.response != nil
{ }
// MARK: - Print data
if response.data != nil
{
let decoder = JSONDecoder()
do
{
let api = try decoder.decode(Main2.self, from: response.data!)
self.sökresultat = api.objects
self.Tableview.reloadData()
}
catch {
print(error.localizedDescription)
print("Error in JSON parsing")
}
}
}
}// MARK: - END
}
这是我的 cell.swift 代码:
import UIKit
class SökrutaCell: UITableViewCell {
@IBOutlet weak var Sökbild: UIImageView!
@IBOutlet weak var Söknamn: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
您有一个 class,其中 @IBOutlet
引用了故事板中的原型单元格。除非使用 dequeueReusableCell(withIdentifier:for:)
.
,否则您不能使用该单元格原型(具有自定义布局)并为您连接插座
如果您的目标是将其与未重复使用的单元格进行比较,您可以通过编程方式实例化 UITableViewCell
并使用内置的 textLabel
和 imageView
属性。例如,您可以:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: "...")
cell.textLabel?.text = ...
cell.imageView?.image = ... // use a placeholder image here or else it won't show the image view at all!
someMethodToFetchImageAsynchronously { image in
// make sure this cell hasn't scrolled out of view!!!
guard let cell = tableView.cellForRow(at: indexPath) else { return }
// if still visible, update its image
cell.imageView?.image = image
}
return cell
}
或者您也可以考虑更复杂的编程模式(您可以在其中添加控件并手动配置它们,这可能是一个更公平的比较)。但以上是一个相当小的实现。
不用说,不推荐这种模式,因为您失去了故事板单元原型的好处和 performance/memory 单元重用的好处。但是,如果您的目标只是比较和对比内存、性能和软件设计注意事项,也许这有助于您了解它。
虽然我试图回答您的问题,但在我担心出列单元格的固有性能之前,您的图像检索机制是一个更大的性能问题。您正在使用不可取消的网络请求 Data(contentsOf:)
获取图像。因此,如果您有一百行,并且您快速向下滚动到第 90..<100 行,那么这 10 行的图像检索将积压为前 90 行的网络请求!此外,您的图像大小是否适合单元格中的小图像视图?这也会显着影响性能和滚动的平滑度。
有许多不错的异步图像检索库。例如。由于您已经在使用 Alamofire,我建议您考虑 AlamofireImage。这提供了很好的异步图像检索机制、很好的 UIImageView
扩展、取消不再需要的请求的能力、图像缓存等。
但是 table 视图的正确异步图像检索是一个非常重要的问题。 AlamofireImage、KingFisher、SDWebImage等图像处理库,可以为你简化这个过程。
我试图在不使用 dequeueReusableCell 的情况下加载我的 tableview,但它只是让我的应用程序崩溃,无法弄清楚我做错了什么?
let cell = Tableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SökrutaCell // THIS CODE WORKS FINE
let cell = SökrutaCell() // THIS CODE CRASHES - Unexpectedly found nil while unwrapping an optional
如果有人能指出我正确的方向,我会很高兴,这样我就能理解失败的原因。
import UIKit
import Alamofire
class Sökruta: UIViewController {
var sökresultat = [Object2]()
@IBOutlet weak var Tableview: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
GetRequest(Url: "https://randomurl.se")
Tableview.delegate = self
Tableview.dataSource = self
Tableview.backgroundColor = UIColor.white
// Do any additional setup after loading the view.
}
}
// MARK: - Delegate extension 1
extension Sökruta: UITableViewDelegate{
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
print("you tapped me!")
}
}
// MARK: - Delegate extension 2
extension Sökruta: UITableViewDataSource{
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return sökresultat.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
// let cell = Tableview.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! SökrutaCell // THIS CODE WORKS FINE
let cell = SökrutaCell() // THIS CODE CRASHES - Unexpectedly found nil while unwrapping an optional
cell.Söknamn.text = sökresultat[indexPath.row].displayname
if let url = URL(string: dontmindthiscode) {
DispatchQueue.global().async {
do {
let data = try Data(contentsOf: url)
DispatchQueue.main.async {
cell.Sökbild.image = UIImage(data: data)
}
} catch let err {
print("error: \(err.localizedDescription)")
}
}
}
else
{
DispatchQueue.main.async {
cell.Sökbild.image = UIImage(systemName: "eye.slash")
}
}
return cell
}
}
// MARK: - Extension functions
extension Sökruta{
// MARK: - GET REQUEST
func GetRequest(Url: String) {
// MARK: - Login details
let headers: HTTPHeaders = [
.authorization(username: "username", password: "password"),
.accept("application/json")]
// MARK: - Api request
AF.request(result, headers: headers).validate().responseJSON { response in
// MARK: - Check for errors
if let error = response.error
{
print (error)
return}
// MARK: - Print response
if response.response != nil
{ }
// MARK: - Print data
if response.data != nil
{
let decoder = JSONDecoder()
do
{
let api = try decoder.decode(Main2.self, from: response.data!)
self.sökresultat = api.objects
self.Tableview.reloadData()
}
catch {
print(error.localizedDescription)
print("Error in JSON parsing")
}
}
}
}// MARK: - END
}
这是我的 cell.swift 代码:
import UIKit
class SökrutaCell: UITableViewCell {
@IBOutlet weak var Sökbild: UIImageView!
@IBOutlet weak var Söknamn: UILabel!
override func awakeFromNib() {
super.awakeFromNib()
// Initialization code
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
您有一个 class,其中 @IBOutlet
引用了故事板中的原型单元格。除非使用 dequeueReusableCell(withIdentifier:for:)
.
如果您的目标是将其与未重复使用的单元格进行比较,您可以通过编程方式实例化 UITableViewCell
并使用内置的 textLabel
和 imageView
属性。例如,您可以:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = UITableViewCell(style: .default, reuseIdentifier: "...")
cell.textLabel?.text = ...
cell.imageView?.image = ... // use a placeholder image here or else it won't show the image view at all!
someMethodToFetchImageAsynchronously { image in
// make sure this cell hasn't scrolled out of view!!!
guard let cell = tableView.cellForRow(at: indexPath) else { return }
// if still visible, update its image
cell.imageView?.image = image
}
return cell
}
或者您也可以考虑更复杂的编程模式(您可以在其中添加控件并手动配置它们,这可能是一个更公平的比较)。但以上是一个相当小的实现。
不用说,不推荐这种模式,因为您失去了故事板单元原型的好处和 performance/memory 单元重用的好处。但是,如果您的目标只是比较和对比内存、性能和软件设计注意事项,也许这有助于您了解它。
虽然我试图回答您的问题,但在我担心出列单元格的固有性能之前,您的图像检索机制是一个更大的性能问题。您正在使用不可取消的网络请求 Data(contentsOf:)
获取图像。因此,如果您有一百行,并且您快速向下滚动到第 90..<100 行,那么这 10 行的图像检索将积压为前 90 行的网络请求!此外,您的图像大小是否适合单元格中的小图像视图?这也会显着影响性能和滚动的平滑度。
有许多不错的异步图像检索库。例如。由于您已经在使用 Alamofire,我建议您考虑 AlamofireImage。这提供了很好的异步图像检索机制、很好的 UIImageView
扩展、取消不再需要的请求的能力、图像缓存等。
但是 table 视图的正确异步图像检索是一个非常重要的问题。 AlamofireImage、KingFisher、SDWebImage等图像处理库,可以为你简化这个过程。