## やりたいこと
SearchRootVC
クラスにて、URLSessionのコードをRepositoryApi
クラスから呼び出したい。
SearchRootVC
1 var repositoryApi = RepositoryApi() 2 3... 4 5 func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { 6 repositoryApi.getRandomRepoUrlSession() 7 }
RepositoryApi
1 2// URLSessionの処理
## selfが原因の、EXC_BAD_ACCESSが出る
EXC_BAD_ACCESS
エラーにて、
self = CodeCheck_Test_Yumemi.SearchRootVC 0x00007ff8c083db00
だと エラー原因が特定出来たので、
下記を記述してself
の使用を避けようとしましたが、引き続きEXC_BAD_ACCESS
でクラッシュします...
RepositoryApi
1var searchRootVC = SearchRootVC()
## URLSessionコード
なお、呼び出しをせずにSearchRootVC
のみで実行すると
EXC_BAD_ACCESS
は無く、正常に動作します。
RepositoryApi
1import UIKit 2 3class RepositoryApi: SearchRootVC { 4 5 var searchRootVC = SearchRootVC() 6 7 8 func getRandomRepoUrlSession() { 9 10 let word = searchBar.text! 11 let REPOSITORY_URL = URL_BASE + "(word)" 12 13 // nilは許さない。urlの強制アンラップを修正。 14 guard let url = URL(string: REPOSITORY_URL) else { return } 15 16 let task = URLSession.shared.dataTask(with: url) { (data, responce, error) in 17 18 guard error == nil else { 19 debugPrint(error.debugDescription) 20 return 21 } 22 23 // dataの強制アンラップを修正。 24 guard let data = data else { return } 25 26 // try!は、例外が発生したときにはクラッシュするので修正。(-> エラーが起こり得ないケースでのみ使用可) 27 // try?で例外を安全に無視できるが、エラーを表示するため do-catch を使用。 28 29 do { 30 let json = try JSONSerialization.jsonObject(with: data) as? [String: Any] 31 if let items = json?["items"] as? [[String: Any]] { 32 self.searchRootVC.repo = items 33 // DispatchQueue で一つ以上のタスクを管理し、async で複数のAPIの非同期通信を実行。 34 DispatchQueue.main.async { 35 // UIを更新する処理 36 self.searchRootVC.tableView.reloadData() 37 } 38 } 39 } catch { 40 debugPrint(error.localizedDescription) 41 return 42 } 43 } 44 // 新しく初期化されたタスクは一時停止状態で開始されるため、このメソッドを呼び出してタスクを開始する必要がある。 45 task.resume() 46 } 47 48} 49 50
SearchRootVC全文
SearchRootVC
1import UIKit 2 3class SearchRootVC: UITableViewController, UISearchBarDelegate { 4 5 @IBOutlet weak var searchBar: UISearchBar! 6 7 // Var 8 var word: String! 9 var url: String! 10 var RepoToPass: Int! 11 12 var task: URLSessionTask? 13 var repo: [[String: Any]]=[] 14 15 var repositoryApi = RepositoryApi() 16 17 override func viewDidLoad() { 18 super.viewDidLoad() 19 setupTableView() 20 } 21 22 // 以下3つ、元から用意されているsearchBar関数名なので、変更NG。 23 func searchBarShouldBeginEditing(_ searchBar: UISearchBar) -> Bool { 24 searchBar.text = "" 25 return true 26 } 27 28 func searchBar(_ searchBar: UISearchBar, textDidChange searchText: String) { 29 task?.cancel() 30 } 31 32 func searchBarSearchButtonClicked(_ searchBar: UISearchBar) { 33 repositoryApi.getRandomRepoUrlSession() 34 } 35 36 func setupTableView() { 37 // UISearchBarのdelegateプロパティに、self(=SearchRootVC)を代入。 38 searchBar.delegate = self 39 } 40 41 override func prepare(for segue: UIStoryboardSegue, sender: Any?) { 42 if segue.identifier == Segues.ToProfileDetail { 43 if let detailVC = segue.destination as? ProfileDetailVC { 44 detailVC.selectedUser = self 45 } 46 } 47 } 48} 49 50 51// extension 52 53extension SearchRootVC { 54 55 override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 56 return repo.count 57 } 58 59 override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 60 61 // dequeueReusableCellで、セルを再利用。 62 // nilを返さない為、オプショナルバインディングは不要。 63 64 let cell: RepositoryCell = tableView.dequeueReusableCell(withIdentifier: Identifiers.RepositoryCell, for: indexPath) as! RepositoryCell 65 let UserRepo = repo[indexPath.row] 66 cell.configureCell(UserRepo) 67 cell.tag = indexPath.row 68 return cell 69 } 70 71 override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 72 RepoToPass = indexPath.row 73 performSegue(withIdentifier: Segues.ToProfileDetail, sender: self) 74 } 75} 76
質問は以上です。
お時間あるときに、ご返信頂けましたら幸いです????
![guest](/img/icon/icnUserSample.jpg)
回答1件
あなたの回答
tips
プレビュー