質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Swift

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

Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

Q&A

解決済

2回答

2802閲覧

UITextViewの処理が重い

退会済みユーザー

退会済みユーザー

総合スコア0

Swift

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

Swift 2

Swift 2は、Apple社が独自に開発を行っている言語「Swift」のアップグレード版です。iOSやOS X、さらにLinuxにも対応可能です。また、throws-catchベースのエラーハンドリングが追加されています。

0グッド

0クリップ

投稿2016/04/09 23:42

編集2016/04/12 08:06

現在、Twitterのタイムラインを表示するUITableViewを作っているのですが、どうしてもスクロールがカクついてしまいます。
セル生成の処理速度を測ってみたところ、テキストの分量が50文字くらいになると生成するのに0.01秒を超えてしまいます。
StoryboardでUITextViewのSelectableとDetectionのLinkをtrueにしています。

Swift

1func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 2 3 self.tweet = self.TweetsJson![indexPath.row] 4 var cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath) as? TableViewCell 5 6 cell!.TextView.text = tweet!["text"].stringValue; 7 8 cell!.nameLabel.text = tweet!["user"]["name"].stringValue; 9 cell!.screenNameLabel.text = "@" + tweet!["user"]["screen_name"].stringValue; 10 11 let url : NSURL = NSURL(string:tweet!["user"]["profile_image_url"].stringValue.stringByReplacingOccurrencesOfString("normal", withString: "bigger"))! 12 13 14 cell!.iconImage.af_setImageWithURL(url,placeholderImage: UIImage(named: "icon_placeholder")!) 15 16 return cell! 17 }

TextView

Swift

1cell!.TextView.text = tweet!["text"].stringValue;

0.0032秒
nameLabel

Swift

1cell!.nameLabel.text = tweet!["user"]["name"].stringValue;

0.0012秒
screenNameLabel

Swift

1cell!.screenNameLabel.text = "@" + tweet!["user"]["screen_name"].stringValue;

0.0014秒
iconImage

Swift

1let url : NSURL = NSURL(string:tweet!["user"]["profile_image_url"].stringValue.stringByReplacingOccurrencesOfString("normal", withString: "bigger"))! 2cell!.iconImage.af_setImageWithURL(url,placeholderImage: UIImage(named: "icon_placeholder")!)

0.003秒

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

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

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

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

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

fuzzball

2016/04/10 07:26

どうやって速度を計ったのか教えて下さい。
fuzzball

2016/04/10 08:45

cellForRowAtIndexPathの最初と最後の間の時間を計ると0.01秒overだったということでしょうか?もう少し細かい処理単位で時間を測って、もしくは、各処理を1つずつコメントアウトして、どの処理が重いのか特定して下さい。
退会済みユーザー

退会済みユーザー

2016/04/11 00:47

おっしゃる通り最初とreturnの直前の間を測っています。 一つ一つ調べてみたところ、UILabel.textをいじっているところで時間がかかっていました。
guest

回答2

0

ベストアンサー

こっちに移動します。

UILabel.textをいじっているところで時間がかかっていました。

Q1. nameLabelとscreenNameLabelの両方ともでしょうか?
Q2. 質問に書かれている「テキストの分量が50文字くらいになると」というのはTextViewのことでしょうか?
Q2'-a. Q2がYesの場合、TextView.textに代入している行をコメントアウトしてもカクつくでしょうか?
Q2'-b. さらに、image関係の行をコメントアウトしてもカクつくでしょうか?
Q3. nameLabelとscreenNameLabelに設定している文字列の長さはどれくらいでしょうか?

#時間計測

最初の2行と最後の1行はそのままで、中身をそれぞれ1つだけの設定にした場合の時間を教えて下さい。

##TextView

swift

1cell!.TextView.text = tweet!["text"].stringValue;

##nameLabel

swift

1cell!.nameLabel.text = tweet!["user"]["name"].stringValue;

##screenNameLabel

swift

1cell!.screenNameLabel.text = "@" + tweet!["user"]["screen_name"].stringValue;

##iconImage

swift

1let url : NSURL = NSURL(string:tweet!["user"]["profile_image_url"].stringValue.stringByReplacingOccurrencesOfString("normal", withString: "bigger"))! 2cell!.iconImage.af_setImageWithURL(url,placeholderImage: UIImage(named: "icon_placeholder")!)

投稿2016/04/11 01:36

編集2016/04/11 04:29
fuzzball

総合スコア16731

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

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

退会済みユーザー

退会済みユーザー

2016/04/11 01:51

A1. nameLabelとscreenLabelの両方です。 A2. はい。その通りです。 A2'-a. コメントアウトして実行してもやはりUILabelの部分で時間がかかり多少カクつきます。 A2'-b. image関連の部分では0.002~3秒かかっているようで、コメントアウトするとカクつかなくなります。 A3. nameLabelは10文字前後、screenNameLabelは20文字弱です。
fuzzball

2016/04/11 07:22 編集

よく分からなくなってしまったので、もう一度時間計測をお願いします。(質問に追記してます) あと、セルの高さはどうなっているでしょうか?固定値でしょうか?可変でしょうか?可変の場合は、どうやって求めているか教えて下さい。 【追記】 カクつくのは置いておいて、TextViewやLabelの内容は正しく表示されているのでしょうか?また、self.tweetの型を教えてもらえますか?
退会済みユーザー

退会済みユーザー

2016/04/12 08:10

TextViewやLabeはきちんと表示されています。 self.tweetはSwiftyJSONのJSON型です。
fuzzball

2016/04/12 09:02

SwiftyJSONを調べてみましたが、単純に処理が重いですね。 あらかじめDictionary型に変換しておくか、他の(軽い)ライブラリを使いましょう。
退会済みユーザー

退会済みユーザー

2016/04/13 06:07

ありがとうございました。Dictionary型にキャストすることにします。
guest

0

全体的な話として、同期的にデータを取ってきて、表示しているように見えますが、
スムーズなスクロールをさせようとするなら、データ取得部分は別で動かして、非同期処理しないと、カクカクしてしまうかと。
af_setImageWithURLで同期で画像ロードしてたりとか、これ結構コストかかりますよね???

なので、
TableViewとは、別にデータロードなどの管理オブジェクト(とか配列)とか、持っておき、
cellForRowAtIndexPath
では、即座にその内容を(ロードされていれば)返却するようにしないと、スムーズにはなりません。
といっても、以外と面倒な処理ですけどね。。。

投稿2016/04/10 01:01

ItoTomonori

総合スコア1283

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

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

退会済みユーザー

退会済みユーザー

2016/04/10 01:34

TweetsJsonにデータを入れています。非同期でデータを取得とは、配列からオブジェクトなどにデータを入れ替えることを指しているのでしょうか? また、af_setImageWithURLにplaceholderImage引数を与えると非同期で画像を取得する、という風に書かれていたサイトがあったような気がするのですが、やはりこれは同期処理になっているのでしょうか?
ItoTomonori

2016/04/10 04:27

大変しつれいいたしました。 どうも、af_setImageWithURLと、placeholderImageで、非同期ロードできるようですね、、、このあたり実動作はみたことないので、なんともですが。。。 非同期ロードとは、データの取得と、描画を分けることで、 描画側はデータのロードの状態に関係なく、描画を行うようにして、実装を行うことです。 よって、描画側は、データの取得の時間にかかわらず決まった時間で処理を行うことができます。 ちなみに、 「テキストの分量が50文字くらいになると生成するのに0.01秒を超えてしまいます」 となっていますが、それでも画面に表示されているセルの分だけですので、通常は10個とか?そのような数ですから、描画にはあまり影響ないような??? あと、通常セルは描画される直前(たとえば、画面にみえてくる前)に生成されるため、スクロールしている段階で、都度生成されているはずです。このあたりトレースを入れてみてみるとよいかと思います。 セルの生成以外で時間かかっている場所はないでしょうかね?
退会済みユーザー

退会済みユーザー

2016/04/10 07:56

ありがとうございます。データの取得はviewDidLoadの中で行い、フラグを立てて描画するようにしています。 時間がかかっている場所を一つずつ調べてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問