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

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

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

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

Q&A

1回答

2565閲覧

swift メモリ破棄

tosi_1211

総合スコア138

Swift

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

0グッド

0クリップ

投稿2016/08/27 17:56

編集2016/08/31 01:20

現在CustomViewでAVPayerを使って動画を流しているのですが、
addPeriodicTimeObserverForIntervalこのメソッドのところを記述してから遷移してもメモリが破棄されなくなってしまいました。何が原因なのでしょうか?

swift

1class CustomView { 2var player: AVPlayer! 3@IBOutlet weak var slider: UISlider! 4private var token: dispatch_once_t = 0 5 6func setPlayer() { 7 if let url = NSURL(string: ("動画URL")!) { 8 let player = AVPlayer(URL: url) 9 let playerlayer = AVPlayerLayer(player: player) 10 self.player = player 11 playerlayer.frame = CGRect(x: 0, y: 0, width: self.frame.width, height: self.rame.height) 12 self.layer.addSublayer(playerLayer) 13 player.play() 14 playerlayer.addSublayer(slider.layer) 15 } 16} 17 18func setSlider() { 19 slider.value = 0 20 slider.minimumValue = 0 21 slider.maximumValue = 60 22 let interval : Double = Double(0.5 * slider.maximumValue) / Double(slider.bounds.maxX) 23 let time : CMTime = CMTimeMakeWithSeconds(interval, Int32(NSEC_PER_SEC)) 24 player?.addPeriodicTimeObserverForInterval(time, queue: dispatch_get_main_queue()) { (time) -> Void in 25 let time = CMTimeGetSeconds(self.player!.currentTime()) 26 let value = Float(self.slider.maximumValue - self.slider.minimumValue) * Float(time) / Float(60) + Float(self.slider.minimumValue) 27 self.finish(time) 28 self.slider.value = value self.timeLabel.text = "0:0\(Int(time)) 29 } 30} 31 32 func finish(time: Float64) { 33 if time >= Float64(60) { 34 dispatch_once(&self.token) { 35 self.player?.pause() 36 self.player?.seekToTime(CMTimeMakeWithSeconds(0, Int32(NSEC_PER_SEC))) 37 } 38 } 39 } 40}

1分たったら、動画を止めるメソッドです。

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

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

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

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

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

fuzzball

2016/08/29 02:14

addPeriodicTimeObserverForIntervalの中のBlocksは質問に書かれているようにカラなのでしょうか?また、「メモリが破棄されない」と思った根拠を書いてください。
tosi_1211

2016/08/29 15:24

Blocks内で、 let time = CMTimeGetSeconds(self.player!.currentTime()) let value = Float(self.slider.maximumValue - self.slider.minimumValue) * Float(time) / Float(10) + Float(self.slider.minimumValue) self.finish(time) self.slider.value = value self.timeLabel.text = "0:0\(Int(time))" 動画の現在時間を取得して、ラベルのテキストに表示しています。 xcodeの左側のmenubarの CPUをみるところで、Memoryが動画を再生するたびに増えていきます。
fuzzball

2016/08/30 00:17

self.finishは何をしているのでしょうか?コードを教えて下さい。(コードは質問内に追記して下さい。ここに書かれると見難いです)
tosi_1211

2016/08/30 14:10

追記しました!
fuzzball

2016/08/30 23:52

こちらで症状を再現させてから調べようと思っていましたが、情報を出していただくたびに不明点が出てくる状態で、これではキリがないので対応を中止します。他の方からの回答をお待ち下さい。
tosi_1211

2016/08/31 01:21

わかりました。ご丁寧な対応ありがとございました。
guest

回答1

0

動画再生されるたびにメモリ使用量が増えるとありますが、**setPlayer()**は、再生するたびに毎回呼ばれますか?

投稿2016/08/31 02:11

Asunaro

総合スコア104

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

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

tosi_1211

2016/08/31 02:14

毎回呼ばれています!
Asunaro

2016/08/31 02:18

回答ありがとうございます。 setFrame()内の下記コードが気になりました。 >self.layer.addSublayer(playerLayer) 再生されるたびにAVPlayerが生成されて、self.layerに対して貼り付けているようにみえるのですが。。。 (以前にaddしているAVPlayerがremoveされているのであれば、すみません!)
Asunaro

2016/08/31 02:20

すみません、setPlayerでした。。。 あと、毎回Playerを生成したり、PlayerLayerを生成する必要があるのでしょうか?
tosi_1211

2016/08/31 02:34

認識違いでした、setPlayerはinit時にしか呼ばれないです!
Asunaro

2016/08/31 02:39

であれば、動画再生はどこでコールされますか? 記載して頂いているソースコードでは、setPlayer()でしか再生していないように見えます。
tosi_1211

2016/08/31 02:45

動画再生もsetPlayerでのみplayしています。 画面遷移したと同時に動画を流す仕様を作っています。
tosi_1211

2016/08/31 02:48

addPeriodicTimeObserverForIntervalこのメソッドの中をすべて消したらメモリが破棄されたので、そこに問題があります。
Asunaro

2016/08/31 03:00

すみません、問題点を見失っていました。 addPeriodicTimeObserverForIntervalは、通知をObserverに対して登録するため、画面を離れる際に通知をremoveしてあげる必要があります。 多分ですが、通知登録したまま画面遷移したことでObserverに情報が残ってしまい、ブロック内に書かれているplayerやsliderの参照が外れず解放されていないのではと思われます。 因みにObserver解除は、下記になります。 removeTimeObserver
tosi_1211

2016/08/31 04:10

ブロック内に書かれているplayerやsliderの参照が外れず解放されていないのではと思われます。 参照の開放はどのようにすればいいのでしょうか?
Asunaro

2016/08/31 05:43

メモリ管理方式がARCなので、playerやsliderの参照(このオブジェクトを知っている人)がなくなれば、勝手に解放されます。 今回参照を持っている人は、ブロック自体になるのでこのブロック自体がなくなれば、参照が消えます。 よって、オブジェクトがメモリから解放されるはずです。 (playerは、強参照になっているため) なので、playerに対して、removeTimeObserver()をコールしてみてください。
tosi_1211

2016/08/31 08:44

ありがとうございます!実装してみます。
tosi_1211

2016/09/01 06:41

removeTimeObserverしたのですがダメでした。
tosi_1211

2016/09/01 06:41

let time = CMTimeGetSeconds(self.player!.currentTime()) 原因を突き詰めたところ、ブロック内のこの一行が悪さをしていました。
tosi_1211

2016/09/01 06:41

しかしどうすれば良いのかがわかりません。
Asunaro

2016/09/02 02:54

>removeTimeObserverしたのですがダメでした 具体的にどの箇所に追加してダメだったか等を記載して頂かないと原因の追求が出来ません。
tosi_1211

2016/09/02 07:52

self.player.addPeriodicTimeObserverForInterval(CMTimeMake(150, 600), queue: dispatch_get_main_queue(), usingBlock: {[unowned self](time) in }) addPeriodicTimeObserverForIntervalメソッドを[unowned self]とすることで解決いたしました
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問