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

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

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

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

Xcode

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

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Swift 2

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

Q&A

2回答

4956閲覧

UITableViewCellがメモリーリークしてしまう

cherish

総合スコア47

iOS

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

Xcode

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

Swift

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

iPhone

iPhoneとは、アップル社が開発・販売しているスマートフォンです。 同社のデジタルオーディオプレーヤーiPodの機能、電話機能、インターネットやメールなどのWeb通信機能の3つをドッキングした機器です。

Swift 2

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

0グッド

2クリップ

投稿2015/11/23 14:12

UITableVIewCellがメモリーリークを起こしてしまい困っています。
cellの使い方としては、ググるとよくでてくるような一般的な使い方だと思います。

swift

1func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 2 let cell: LocationFeedTableViewCell = tableView.dequeueReusableCellWithIdentifier("MyCell", forIndexPath: indexPath) as! LocationFeedTableViewCell 3 4 (省略) 5 6 return cell 7 }

症状としては、テーブルをスクロールするたびにメモリが溜まり続けていってしまいます。
希望としては、cellの再利用のタイミングや画面外に外れたタイミングでメモリーを解放して欲しいのですが、うまくいきません。
何か良い方法をご存知の方がいましたら、ご教示いただけるとありがたいです。
よろしくお願いいたします。

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

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

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

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

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

Stripe

2015/11/23 14:16

なぜ、メモリリークしているのがUITableViewCellだと分かったのですか?
cherish

2015/11/23 21:57

たしかに、そう言われると確証は持てないですね。TableViewをスクロールするとメモリが増え続けるため、TableVIewCellのせいだと考えていますが、他の部分が原因となっている可能性も捨てずに調べてみたいと思います。
guest

回答2

0

回答ではなく同様の問題で困っております。
私はUITableViewCellを継承してカスタムセル(MATableViewCell)を作っております。
ビューはxibで定義しています。
MATableViewCellにinitCellというメソッドを定義しており、
セル表示データを更新しています。
引数も参照渡しにし、特に大きなオブジェクトは作成しないように気をつけているにもかかわらず、
keima様と同様の問題が起きて困っております。
このinitCellを呼び出さないとメモリは増えません。
cell内のビューが多重に生成されているのでしょうか。。。

Swift

1 // セルデータ初期化 2 internal func initCell(inout men: Men) { 3 if iconImage != nil && men.image1 != nil { 4 iconImage!.image = men.image1 5 } 6 shopName.text = men.shopname 7 katasaMeter.setProgress(Float(men.katasa) / 10.0 + 0.05, animated: false) 8 katasaScore.text = String(men.katasa) 9 kosaMeter.setProgress(Float(men.kosa) / 10.0 + 0.05, animated: false) 10 kosaScore.text = String(men.kosa) 11 aburaMeter.setProgress(Float(men.abura) / 10.0 + 0.05, animated: false) 12 aburaScore.text = String(men.abura) 13 //visitDate.text = Utils.formatPickerDateTime(men.date!, style: "y-M-d") 14 memo.text = men.memo 15 score.setScore(men.score) 16 }

投稿2015/11/27 03:35

tajitaji552

総合スコア14

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

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

TakeOne

2015/11/27 04:26

initCellを呼び出さないようにするとメモリが増えないのであれば、今度はそのinitCell内の各行を少しずつ削除して行って、どこでメモリが増えなくなるか調べれば、なにかわかるのではないでしょうか? 元の質問と同じ現象に見えたとしても、やっていることが全く違うのですから、その調べ方も原因も違うはずです。解決しないようなら、ちゃんと新たに質問をたてた方がよいと思います。ここで回答エリアに便乗質問を入れても、見ているのは元の質問者とここに回答を入れている回答者くらいです。 また、新たに質問を立てる場合、initCellメソッドの内容だけでなく、MATableViewCellクラス全体や、そのMATableViewCellを使っている場所の処理を説明した方がよいと思います。 そもそも「使用メモリが増えている」のが、どれくらい増えていて、どうおかしいのかも具体的に示さないと、セルが再利用待ちの間に保持されている分が増えただけじゃないですか?という回答になりかねません。
guest

0

よくあるのは、その「(省略)」となっているコードの中でボタン等の部品をaddSubviewでセルに貼り付け、セルを再利用するたびに、以前にaddSubviewした部品を削除しないでどんどんaddSubviewで重ね貼りしてしまうケースだと思います。

投稿2015/11/23 17:26

編集2015/11/23 23:07
TakeOne

総合スコア6299

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

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

cherish

2015/11/24 14:17

アドバイスありがとうございます。下記のようにcellを再利用する際に、viewを取り除く処理を加えたところ、かなり改善されました。 let subviews = self.subviews for subview in subviews { subview.removeFromSuperview() } しかし、依然としてスクロールを行うとメモリが増え続ける症状が続いています。 何箇所かコメントアウトしながら調べたところ下記のような感じでcellの中で動画を再生させているのですが、そちらでメモリの未開放が起こっているようです。 let fileURL = NSURL(string: feedValues.movieUrl!) let avAsset = AVURLAsset(URL: fileURL!, options: nil) playerItem = AVPlayerItem(asset: avAsset) let movieView: UIView = UIView() movieView.frame = CGRectMake(0, 0, myBoundSize.width, myBoundSize.width) videoPlayer = AVPlayer(playerItem: playerItem) videoPlayer.muted = true let videoPlayerView = AVPlayerView(frame:CGRectMake(0, 0, myBoundSize.width, myBoundSize.width)) let layer = videoPlayerView.layer as! AVPlayerLayer layer.videoGravity = AVLayerVideoGravityResizeAspect layer.player = videoPlayer videoPlayer.play() movieView.layer.addSublayer(layer) self.addSubview(movieView)
TakeOne

2015/11/24 16:28

もしかして、各セル毎にAVPlayerとAVPlayerLayerを生成し、 全てを同時再生しているのでしょうか? 全てを同時再生しているのだったら、各動画の音声も同時出力 されて聞き取れなくなると思うのですが、このあたりはやはり 同時には1個だけの再生になるようどこかで制御しているのでしょうか? そのあたりをどう制御しているかよく見えませんが、 特に何もしてないのだったら、セルが再利用待ちの間もずっと 動画再生は生きており、再利用待ちセルがたまるのと比例して 消費メモリも増えると思います。 そのあたりを見直すとよいように思えました。 ちなみに、同様のことをしている有名アプリとしてVineがありますが、 Vineでは同時に再生される動画は1個で、音声もその再生中の動画だけ 音声が流れますよね。
cherish

2015/11/25 01:22

度々ご回答いただき誠にありがとうございます。 動画を一つづつしか再生しない処理を入れているのですが、それを取り除いたところ、全ての動画が再生されてしまい、スクロールするごとに再生される動画が増えてしまっています。 cellの再利用時にAVPlayerがうまく削除されていないようです。 AVPlayerを削除する方法を考えてみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.49%

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

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

質問する

関連した質問