jsonからデータを取得し、それを非同期通信で配列に入れ画面に表示させるページに、
引っ張って画面を更新する機能を実装してみたのですが、
強く下に引っ張ったり、3回のうち1回くらいのペースでクラッシュしてしまいます。
軽く引っ張るくらいで更新処理が進む場合はあまりクラッシュしないですが、
強く引っ張るとほとんどの確率でクラッシュしてしまいます。
予想外の強さで引っ張ってしまった時にcellectioViewのセルのインデックス番号に不具合か何かあるのでしょうか?
また、回避策などございますでしょうか?
ちなみに、引っ張って更新を付ける前は一度もエラーはありませんでした。
エラーコードはこちらです。
Fatal error: Index out of range
文中のprint文の表示は以下のようになります
インデックス:0 インデックス:1 インデックス:2 インデックス:3 インデックス:4 インデックス:5 インデックス:4
コード本文
import UIKit import Alamofire import AlamofireImage import SwiftyJSON class ViewController: UIViewController,UICollectionViewDataSource,UICollectionViewDelegate{ @IBOutlet weak var collectionView: UICollectionView! //Appdelegateのインスタンス生成 var appdelegate:AppDelegate = UIApplication.shared.delegate as! AppDelegate var imageURL_box:[String] = [] var title_box:[String] = [] var publisher_box:[String] = [] var articleURL_box:[String] = [] //引っ張って更新のやつ private var refreshControl = UIRefreshControl() override func viewDidLoad() { super.viewDidLoad() //下に引っ張って更新 refreshControl = UIRefreshControl.init() refreshControl.attributedTitle = NSAttributedString(string: "引っ張って更新") refreshControl.addTarget(self, action: #selector(ViewController.refresh(sender:)), for: .valueChanged) if #available(iOS 10.0, *) { collectionView.refreshControl = refreshControl } else { // Fallback on earlier versions collectionView.addSubview(refreshControl) } } // refresh処理 @objc func refresh(sender: UIRefreshControl) { self.dateSet() DispatchQueue.main.asyncAfter(deadline: .now() + 2.0) { // 完了したらUIRefreshControlのendRefreshing()を呼ばないとくるくるが終わらない self.refreshControl.endRefreshing() } } override func viewWillAppear(_ animated: Bool) { print("viewWillAppear呼ばれた") dateSet() } //非同期通信して配列にデータ入れる func dateSet(){ self.title_box.removeAll() self.publisher_box.removeAll() self.imageURL_box.removeAll() self.articleURL_box.removeAll() let request = URLRequest(url: URL(string: "http://~.json")!, cachePolicy: .reloadIgnoringLocalCacheData, //キャッシュ残らせない timeoutInterval: 5.0) //非同期通信 Alamofire.request(request).validate().responseJSON { response in switch response.result { case .success(let value): let json = JSON(value) print(json) for i in 0 ..< json.count{ self.title_box.append(json[i]["articleTitle"].string!) self.publisher_box.append(json[i]["siteTitle"].string!) self.articleURL_box.append(json[i]["articleURL"].string!) self.imageURL_box.append(json[i]["imageURL"].string!) } } case .failure(let error): print(error) } self.collectionView.reloadData() } } //セルの個数指定するデリゲートメソッド func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int { return self.imageURL_box.count } //セルに値を追加するデリゲートメソッド func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell { let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath) as! CollectionViewCell print("インデックス:(indexPath.row)") cell.news_detail_lbl.text = self.title_box[indexPath.row] cell.news_publisher_lbl.text = self.publisher_box[indexPath.row] //画像が読み込まれるまでのimage let placeholder = UIImage(named: "img1") let filter = AspectScaledToFitSizeFilter(size: CGSize(width: 375, height: 130)) //画像urlが取得出来てない,""の場合 //AlamofireImage使用 if self.imageURL_box[indexPath.row] != ""{ cell.newsImage.af_setImage(withURL: URL(string: self.imageURL_box[indexPath.row])!,placeholderImage: placeholder, filter: filter) }else{ cell.newsImage.image = UIImage(named: "img2") } return cell } } class CollectionViewCell :UICollectionViewCell{ @IBOutlet weak var newsImage: UIImageView! @IBOutlet weak var news_detail_lbl: UILabel! @IBOutlet weak var news_publisher_lbl: UILabel! }
回答3件
あなたの回答
tips
プレビュー
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。