如何解决UITableView willDisplay 在调用 API 分页时不断调用自己,问题是异步 API 调用
我正在使用 MVVM 并且这个 tableview 委托在 ViewController 中 问题是因为API调用函数使用了viewmodel对象
func tableView(_ tableView: UITableView,willdisplay cell: UITableViewCell,forRowAt indexPath: IndexPath) {
if indexPath.row == photosVM.albumData.photos!.photo!.count - 1 {
if photosVM.albumData.photos!.pages! >= photosVM.albumData.photos!.page! {
spinner.color = UIColor.FlickrAlbum_theme
spinner = UIActivityIndicatorView(style: .medium)
spinner.startAnimating()
spinner.frame = CGRect(x: CGFloat(0),y: CGFloat(0),width: tableView.bounds.width,height: CGFloat(44))
tblPhotos.tableFooterView = spinner
tblPhotos.tableFooterView?.isHidden = false
//Calling search API with search keywords
photosVM.getPhotos(pageNumber: photosVM.albumData.photos!.page! + 1,searchText: txtSearch.text!) { [self] (status) in
lblDescription.text = txtSearch.text
if status == "success" {
lblDescription.text = txtSearch.text
tblPhotos.reloadData()
}
else {
//showing error message
showAlert(message: status)
}
}
spinner.stopAnimating()
tblPhotos.tableFooterView = nil
tblPhotos.tableFooterView?.isHidden = true
}
}
这是我的 viewmodel,其中我有一个调用 API 并将数据绑定到视图控制器的功能
func getPhotos(pageNumber: Int = 1,completion: @escaping (String) -> Void) {
let params = GetPhotosBody()
params.format = "json"
params.apiKey = Constants.apiKey
params.nojsoncallback = 1
params.page = pageNumber
params.text = ""
params.contentType = 1
ServerManager.getAllPhotos(params: params) { [self] (status,data) in
if status == "success" {
if pageNumber == 1 {
albumData = data
}
else {
albumData.photos?.page = data?.photos?.page!
albumData.photos?.photo?.append(contentsOf: (data!.photos!.photo!))
}
//Cache Data
DataCache.instance.write(object: albumData.toJSON() as NSCoding,forKey: CacheValue.photos)
}
if let photos = DataCache.instance.readobject(forKey: CacheValue.photos) {
albumData = Mapper<FlickrAlbumPhotosResponse>().map(JSONObject: photos)
}
else {
albumData = nil
}
completion(status)
}
}
这是API调用管理器,我使用completionblock来处理异步方法
public static func getAllPhotos(params: GetPhotosBody,completion: @escaping (String,FlickrAlbumPhotosResponse?) -> Void) {
//creating URL
//addingPercentEncoding is used for encoding the url string to support text with spaces
let url = "\(Constants.baseURL)\(FlickrAlbumEndpoints.getPhotos.rawValue)&format=\(String(describing: params.format!))&nojsoncallback=\(String(describing: params.nojsoncallback!))&api_key=\(String(describing: params.apiKey!))&page=\(String(describing: params.page!))".addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed)!
//creating request
var request = URLRequest(url: URL(string: url)!)
request.httpMethod = HTTPMethod.get.rawValue
request.setValue("application/json",forHTTPHeaderField: "Content-Type")
//Making request to the server to call the API
Alamofire.request(request).responSEObject { (response: DataResponse<FlickrAlbumPhotosResponse>) in
//Check the response of the API
switch response.result {
case .success:
let data = response.result.value
completion("success",data)
case .failure(let error):
completion(error.localizedDescription,nil)
}
}
}
每当我关闭互联网时,它都会一次又一次地显示错误消息,因为它一直在调用遗嘱显示委托。 如果我以错误的方式使用 MVVM,请告诉我并提供您的建议。谢谢
解决方法
我强烈怀疑当 api 调用失败(因为没有互联网)时,您正在将一些缓存数据分配给您的视图模型数组。分配它会触发视图控制器中的绑定函数,该函数重新加载 tableview,因此 api 调用再次进入无限循环。
从您的 api 函数中删除缓存分配,它应该可以正常工作。
,它一直显示错误消息,因为该表在 getSearchPhotos
完成块上一次又一次地重新加载其数据。
重新加载数据将调用表视图委托,然后此过程将循环进行。
photosVM.getSearchPhotos(pageNumber: photosVM.albumData.photos!.page! + 1,searchText: txtSearch.text!) { [self] (status) in
lblDescription.text = txtSearch.text
tblPhotos.reloadData() // why reload here?
// the rest of the code
}
取消注释第一个重新加载代码,如果成功调用 API 则重新加载数据。
,我刚刚从 ViewModel 函数中删除了这些行,现在工作正常。
if let photos = DataCache.instance.readObject(forKey: CacheValue.photos) {
albumData = Mapper<FlickrAlbumPhotosResponse>().map(JSONObject: photos)
}
else {
albumData = nil
}
现在,我在 ViewModel 初始化时处理了那个缓存,它在构造函数中。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。