🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

803閲覧

アプリの立ち上がりが遅い

ramu

総合スコア5

TableView

TableView(UITableView)とは、リスト形式で表示するコントロールで、ほとんどのアプリに使用されています。画面を「行」に分けて管理し、一般的には各行をタップした際に詳細画面に移動します。

iOS

iOSとは、Apple製のスマートフォンであるiPhoneやタブレット端末のiPadに搭載しているオペレーションシステム(OS)です。その他にもiPod touch・Apple TVにも搭載されています。

Xcode

Xcodeはソフトウェア開発のための、Appleの統合開発環境です。Mac OSXに付随するかたちで配布されています。

Swift

Swiftは、アップルのiOSおよびOS Xのためのプログラミング言語で、Objective-CやObjective-C++と共存することが意図されています

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2019/09/10 05:09

#やりたいこと

Swiftのアプリの立ち上がりを早くしたい

#発生している問題

現状立ち上がりに8秒ほどかかっています

#コード

swift

1override func viewDidLoad() { 2 3 super.viewDidLoad() 4 5 ViewController.dateFormater2.dateFormat = "yyyy年MM月dd日" 6 ViewController.dateFormater2.locale = Locale(identifier: "ja_JP") 7 8 ViewController.dateFormater3.dateFormat = "yyyy-MM-dd" 9 ViewController.dateFormater3.locale = Locale(identifier: "ja_JP") 10 11 getToday() 12 ViewController.semaphore = DispatchSemaphore(value: 0) 13 14 for forCount in stride(from: 0, to: 27, by: 1) { 15 ViewController.searchMovie(count: forCount) 16 ViewController.semaphore.wait() 17 } 18 19 for _ in 0..<ViewController.movieReleaseDateList.count-1 { 20 for j in 0..<ViewController.movieReleaseDateList.count-1 { 21 if ViewController.movieReleaseDateList[j] > ViewController.movieReleaseDateList[j+1] { 22 let t = ViewController.movieReleaseDateList[j] 23 ViewController.movieReleaseDateList[j] = ViewController.movieReleaseDateList[j+1] 24 ViewController.movieReleaseDateList[j+1] = t 25 26 let k = ViewController.movieTitleList[j] 27 ViewController.movieTitleList[j] = ViewController.movieTitleList[j+1] 28 ViewController.movieTitleList[j+1] = k 29 30 let l = ViewController.moviePosterPathList[j] 31 ViewController.moviePosterPathList[j] = ViewController.moviePosterPathList[j+1] 32 ViewController.moviePosterPathList[j+1] = l 33 34 let p = ViewController.DatemovieReleaseDateList[j] 35 ViewController.DatemovieReleaseDateList[j] = ViewController.DatemovieReleaseDateList[j+1] 36 ViewController.DatemovieReleaseDateList[j+1] = p 37 38 let m = ViewController.movieOverviewList[j] 39 ViewController.movieOverviewList[j] = ViewController.movieOverviewList[j+1] 40 ViewController.movieOverviewList[j+1] = m 41 } 42 } 43 } 44 45 getDateBeforeOrAfterSomeWeek(week: -4.3) 46 getDateAfterOrAfterSomeWeek(week: 4.3) 47 var releasedate:Date = Date() 48 49 for releaseDate in ViewController.DatemovieReleaseDateList{ 50 if releaseDate < ViewController.BeforeResultDate || 51 releaseDate > ViewController.AftereResultDate { 52 53 let index = ViewController.DatemovieReleaseDateList.firstIndex(of: releaseDate) 54 55 ViewController.DatemovieReleaseDateList.remove(at: index!) 56 ViewController.movieTitleList.remove(at: index!) 57 ViewController.moviePosterPathList.remove(at: index!) 58 ViewController.movieReleaseDateList.remove(at: index!) 59 ViewController.movieOverviewList.remove(at: index!) 60 } 61 } 62 63 for date in ViewController.DatemovieReleaseDateList { 64 if date != releasedate { 65 ViewController.sectionName.append(date) 66 releasedate = date 67 } 68 } 69 70 for i in 0..<ViewController.sectionName.count { 71 var tmpList = [Int]() 72 for j in 0..<ViewController.DatemovieReleaseDateList.count { 73 if ViewController.sectionName[i] == ViewController.DatemovieReleaseDateList[j] { 74 tmpList.append(j) 75 } 76 } 77 ViewController.koukaibiList.append(tmpList) 78 } 79 80 self.tableView.register(UINib(nibName: "customCellClass", bundle: nil), forCellReuseIdentifier: "tableViewCell") 81 navigationController?.navigationBar.prefersLargeTitles = true 82 self.navigationController?.navigationBar.setBackgroundImage(UIImage(), for: UIBarMetrics.default) 83 self.navigationController?.navigationBar.shadowImage = UIImage() 84 createTable() 85 } 86 87 struct ItemJson: Codable { 88 let original_title: String? 89 let release_date: String? 90 let poster_path: String? 91 } 92 93 struct ResultJson: Codable { 94 var results:[ItemJson]? 95 } 96 97 func getToday(format: String = "yyyyMMdd") -> Date? { 98 ViewController.dateFormater.dateFormat = format 99 ViewController.daystr = ViewController.dateFormater.string(from: ViewController.now as Date) 100 101 ViewController.day = ViewController.dateFormater.date(from: ViewController.daystr as String)! 102 return ViewController.day 103 } 104 105 func getDateBeforeOrAfterSomeWeek(week:Double) -> Date { 106 let now = Date() 107 108 if week > 0 { 109 ViewController.BeforeResultDate = Date(timeInterval: 604800*week, since: now as Date) 110 } else { 111 ViewController.BeforeResultDate = Date(timeInterval: -604800*fabs(week), since: now as Date) 112 } 113 return ViewController.BeforeResultDate 114 } 115 116 func getDateAfterOrAfterSomeWeek(week:Double) -> Date { 117 let now = Date() 118 if week > 0 { 119 ViewController.AftereResultDate = Date(timeInterval: 604800*week, since: now as Date) 120 } else { 121 ViewController.AftereResultDate = Date(timeInterval: -604800*fabs(week), since: now as Date) 122 } 123 return ViewController.AftereResultDate 124 } 125 126 static func searchMovie(count : Int) { 127 guard let req_url = URL(string: "https://api.themoviedb.org/3/movie/upcoming?page=(count)&language=jp&api_key=45cfffebd76a148b4c8907aed12b6eae" 128 ) else { 129 return 130 } 131 let req = URLRequest(url: req_url) 132 133 let task = URLSession.shared.dataTask(with: req, completionHandler: { 134 (data , response , error) in 135 do { 136 let decoder = JSONDecoder() 137 let json = try decoder.decode(ResultJson.self , from: data!) 138 if let resultList = json.results { 139 for results in resultList { 140 if let original_title = results.original_title , var release_date = results.release_date , var 141 poster_path = results.poster_path { 142 if let range = release_date.range(of:"-") { 143 release_date.removeSubrange(range) 144 if let range = release_date.range(of:"-") { 145 release_date.removeSubrange(range) 146 } 147 } 148 if let range = poster_path.range(of:"/") { 149 poster_path.removeSubrange(range) 150 } 151 movieTitleList.append(original_title) 152 moviePosterPathList.append("https://image.tmdb.org/t/p/w500/(poster_path)") 153 movieReleaseDateList.append(Int(release_date)!) 154 DatemovieReleaseDateList.append(ViewController.dateFormater.date(from: release_date)!) 155 } 156 } 157 } 158 semaphore.signal() 159 } catch { 160 print("エラー発生") 161 } 162 }) 163 task.resume() 164 } 165 166 override func didReceiveMemoryWarning() { 167 super.didReceiveMemoryWarning() 168 // Dispose of any resources that can be recreated. 169 } 170 func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 171 return ViewController.koukaibiList[section].count 172 } 173 174 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 175 let cell = tableView.dequeueReusableCell(withIdentifier: "tableViewCell", for: indexPath) as! customCellClass 176 ViewController.sectionNum = indexPath.section 177 cell.cellDisplayControl(indexPath: indexPath) 178 cell.accessoryType = UITableViewCell.AccessoryType.disclosureIndicator 179 return cell 180 } 181 182 func numberOfSections(in tableView: UITableView) -> Int { 183 return ViewController.sectionName.count 184 } 185 func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? { 186 return ViewController.dateFormater2.string(from: ViewController.sectionName[section] as Date) 187 } 188 func tableView(_ tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat { 189 return 40 190 } 191 func createTable() { 192 self.tableView.delegate = self 193 self.tableView.dataSource = self 194 tableView.rowHeight = 110 195 tableView.backgroundColor = UIColor(red:1.1,green:1.1,blue:1.1,alpha:0.9) 196 } 197 198 func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) { 199 tableView.deselectRow(at: indexPath, animated: true) 200 performSegue(withIdentifier: "tomovieDetails", sender: nil) 201 202 ViewController.judge = 0 203 ViewController.section = indexPath.section 204 ViewController.row = indexPath.row 205 } 206}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ボトルネックがどこにあるのかはprofileなどを使って調べてください。
https://qiita.com/takusan_009/items/7c6962640435bc884b29

ソースを見た感じ、UIスレッドをがっつりセマフォで止めているように見えるので、まあそうだろうなという印象です。
iOSアプリは基本的にUIスレッドをなるべく止めないようにした方がいいです。

HTTPアクセスは1個1個終わるのを待つのではなく、並列に処理すればもう少し改善は見込めるかと思いますが、やってみないとわかりません。

投稿2019/09/10 05:36

takabosoft

総合スコア8356

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ramu

2019/09/10 05:47 編集

回答ありがとうございます 並列に処理とは具体的にどういったことをすれば良いですか? セマフォを使わないとレスポンスを全て受け取る前にtableviewを表示してしまうのです。
takabosoft

2019/09/10 06:08

例えば for forCount in stride(from: 0, to: 27, by: 1) { ViewController.searchMovie(count: forCount) } for forCount in stride(from: 0, to: 27, by: 1) { ViewController.semaphore.wait() } のように、signalとwaitの順番を変えることですね。
takabosoft

2019/09/10 06:09

> セマフォを使わないとレスポンスを全て受け取る前にtableviewを表示してしまうのです。 普通は「すべて受け取ったらtableViewを更新する」という考え方をします。それまでグルグル回るやつでも表示しておけばいいです。
takabosoft

2019/09/10 06:10

ちょっと前にもここで同じような回答をした覚えがあるのですが、この手のセマフォを使った方法ってどこかの教材で布教されてるんですかね?
ramu

2019/09/10 06:17

ありがとうございます! 先ほどいただいたコードに変更したところ、起動後すぐにtableviewが表示されました! 教材は使っていません。 確かQiitaで参考にしました(どなたの記事かは忘れました)
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問