在我的应用程序中,我为tableView中的每个单元格设置了不同timeInterval的计时器,我创建了计时器数组,创建了返回Timer的函数setTimer和prepareForReuse使这里的计时器无效是我的自定义表格视图单元格类
class cellForData: UITableViewCell {
@IBOutlet weak var iconImage: UIImageView!
@IBOutlet weak var dataText: UILabel!
var timerArray: Array = [Timer(), Timer(), Timer(), Timer(), Timer(), Timer(), Timer(), Timer(), Timer(), Timer()]
var count: Double = 0
var texts = String()
var countHowMuch = Double()
func setTimer(withInterval: Double, text: String, countTimes: Double) -> Timer {
texts = text
countHowMuch = countTimes
return Timer.scheduledTimer(timeInterval: withInterval, target: self, selector: #selector(handle), userInfo: nil, repeats: true)
}
func handle() {
count += countHowMuch
dataText.text = "\(count) + \(texts)"
}
override func prepareForReuse() {
super.prepareForReuse()
timerArray[timerArray.count - 1].invalidate()
}
}
在ViewController中,我在cellForRow函数中调用函数setTimer,这是
的代码 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "secondVCCell") as? cellForData {
cell.timerArray[indexPath.row] = cell.setTimer(withInterval: arrayOfAStruct[indexPath.row].seconds, text: arrayOfAStruct[indexPath.row].text, countTimes: arrayOfAStruct[indexPath.row].countTimes)
RunLoop.main.add(cell.timerArray[indexPath.row], forMode: .commonModes)
return cell
}
return UITableViewCell()
}
因此,当表格视图滚动的单元格表现奇怪时,这些单元格总是会改变位置,在此之后定时器无法正常工作,我猜计时器甚至不会失效。每当单元格重用并且单元格保持在相同位置时,我需要定时器无效。这是我的整个视图控制器
import UIKit
struct forShowedVC { var image:UIImage! var text:String! var秒:双倍! var countTimes:双倍! }
class showsVC:UIViewController,UITableViewDataSource,UITableViewDelegate {
@IBOutlet weak var myTableView: UITableView!
var arrayOfAStruct = [forShowedVC]()
override func viewDidLoad() {
super.viewDidLoad()
myTableView.dataSource = self
myTableView.delegate = self
arrayOfAStruct = [forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "a", seconds: 1, countTimes: 3),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "b", seconds: 1, countTimes: 2),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "c", seconds: 1, countTimes: 7),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "d", seconds: 1, countTimes: 12),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "e", seconds: 1, countTimes: 1),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "f", seconds: 1, countTimes: 9),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "g", seconds: 1, countTimes: 13),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "h", seconds: 1, countTimes: 71),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "i", seconds: 1, countTimes: 4),
forShowedVC(image: #imageLiteral(resourceName: "pie-chart"), text: "j", seconds: 1, countTimes: 6)]
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
if let cell = tableView.dequeueReusableCell(withIdentifier: "secondVCCell") as? cellForData {
cell.timerArray[indexPath.row] = cell.setTimer(withInterval: arrayOfAStruct[indexPath.row].seconds, text: arrayOfAStruct[indexPath.row].text, countTimes: arrayOfAStruct[indexPath.row].countTimes)
RunLoop.main.add(cell.timerArray[indexPath.row], forMode: .commonModes)
return cell
}
return UITableViewCell()
}
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return arrayOfAStruct.count
}
}
答案 0 :(得分:0)
问题在于每次出列单元格时都会创建一个新计时器,但永远不会使其中任何一个无效。因此,当您滚动代码时,会不断添加更多计时器。以下是我要采取的措施:
将表视图单元类修改为具有弱可选的计时器属性:
@class cellForData: UITableViewCell {
weak var cellTimer: Timer?
//Your other vars and code here
}
然后在你的cellForRowAt方法中,将一个单元格出列并立即使它无效的计时器:
if let cell = tableView.dequeueReusableCell(withIdentifier: "secondVCCell") as? cellForData {
cell.cellTimer?.invalidate()
cell.cellTimer = setTimer(withInterval: arrayOfAStruct[indexPath.row].seconds, selector: #selector(handleObject))
//The rest of your code to configure the cell goes here.
}
通过使单元格cellTimer
成为弱可选项,在计时器运行时,运行循环将保留对计时器的唯一强引用。如果您使其无效,它将被释放并设置为nil。因此,如果单元格没有正在运行的计时器,则代码cell.cellTimer?.invalidate()
中的可选链接不会执行任何操作。
您也可以在表格查看单元格cell.cellTimer?.invalidate()
方法中调用prepareForReuse()
,而不是cellForRowAt