質問編集履歴

1

抜本対応用の説明追加

2016/11/20 03:57

投稿

sirosiro
sirosiro

スコア26

test CHANGED
File without changes
test CHANGED
@@ -1,22 +1,78 @@
1
1
  ###前提・実現したいこと
2
2
 
3
- Objective-cでiOS用アプリを作っています。
3
+ メモリが解放されているかを確認するobjective-cの命令などがあれば知りたかたのですが、抜本対応まで含め考えてくださる方もらっしゃるので、不足していた説明を追加します。
4
4
 
5
- 音楽を再生するアプリなのですが、AVPlayerItemのステータスをobserveValueForKeyPath:ofObject:change:contextを用いて監視して、値が変更された際にイベントを発行しています。
6
5
 
6
+
7
- メモ管理はARCです。
7
+ iTunesのような音楽再生アプを作っております。
8
+
9
+ 自分用のアプリで、公開する予定もなければ家族も友達も使いません。
10
+
11
+
12
+
13
+ アプリ内だけで音楽を再生する分にはご指摘にあったようにAVPlayerItemを使って再生すればいいですし、再生の制御をアプリが行っているので、その際にselfなりに現在再生中の曲情報を持たせてそれを使えばいいです。
14
+
15
+ ただ、iTunesのようにアプリがバックグラウンドになった状態や、iPadの待ち受け状態で曲が終了時に自動的に次の曲に遷移させるにはAVQueuePlayerを使う必要があります。
16
+
17
+ このAVQueuePlayerは複数の曲(AVPlayerItem)が入った**プレイリスト**をArrayの形で渡して再生を任せることができます。曲が終われば自動的に次の曲に遷移してくれます。
18
+
19
+
20
+
21
+ ただ、欠点としてAVQueuePlayerには曲が終わったことや始まったことなどを検知するようなDelegateが存在しないので、仕方なしに
22
+
23
+ ```objc
24
+
25
+ [avPlayerItem addObserver:self
26
+
27
+ forKeyPath:@"status"
28
+
29
+ options:NSKeyValueObservingOptionInitial
30
+
31
+ context:(__bridge void *)(Playlist)];
32
+
33
+ ```
34
+
35
+ このような形でAVQueuePlayerに渡すAVPlayerItem**それぞれ**にaddObserverでstatusプロパティが変更された時にイベントが発生するように細工をしています。これだけでは渡した複数のAVPlayerItemの**どの曲で**イベントが発生したのかわからないのでPlaylistという曲情報が入ったオブジェクトも一緒に渡しています。
36
+
37
+
38
+
39
+ こうすることで、observeValueForKeyPath:ofObject:change:contextが呼ばれた際に曲情報やアートワークなどを更新してiPadなどで現在再生中の内容を表示させることに成功しました。
8
40
 
9
41
 
10
42
 
11
43
  ###発生している問題・エラーメッセージ
12
44
 
13
- たまにですが、以下のエラーが発生してアプリが異常終了します。
45
+ ところが、しばらく使っているとたまにですがプレイスト切り替え時に
14
46
 
15
47
  ```
16
48
 
17
49
  Thread 1:EXC_BAD_ACCESS (code=1, address=0x...)
18
50
 
19
51
  ```
52
+
53
+ 上記のエラーが発生してアプリが異常終了します。
54
+
55
+ プレイリストの切り替えは以下のような順で処理をしています。
56
+
57
+
58
+
59
+ 0. 再生を停止する
60
+
61
+ 0. removeObserverでaddObserverしたものを解除
62
+
63
+ 0. PlaylistとAVPlayerItemを解放(ARCなのでnilセット)
64
+
65
+ 0. 新しいPlaylistとAVPlayerItemを作成してセット
66
+
67
+ 0. 再生開始
68
+
69
+
70
+
71
+ ここで、removeObserverして解放した曲のイベントがなぜか発生し、当然ながらすでにARCによって解放されているのでPlaylistにアクセスするとBAD_ACCESSとなります。
72
+
73
+
74
+
75
+ どういう条件でremoveObserverした後にイベントが発生するのかわかりません。ただ、何度か使っているうちに発生します。1回目で突然発生することは今の所ありません。
20
76
 
21
77
 
22
78
 
@@ -66,8 +122,14 @@
66
122
 
67
123
  ###教えて欲しいこと
68
124
 
69
- ARC管理下でcontext内のメモリが自動解放された後にAVPlayerItemにメッセージが飛んできているのが原因と思われますが、(タイミングによってはそうなるのかもしれません)その場合は処理をスキップさせようと思っています。
125
+ ARC管理下でcontext内のメモリが自動解放された後にAVPlayerItemにメッセージが飛んできているのが原因と思われますが、(タイミングによってはそうなるのかもしれません)その場合は**どうせremoveObserverされた後のAVPlayerItemに対して飛んできた謎イベントなので**処理をスキップさせようと思っています。
70
126
 
71
127
 
72
128
 
129
+ 抜本的な解決法(回避法)もあればお願いいたします。
130
+
131
+
132
+
133
+ それと、コメントにあったようにあまり手を加えたくはありません。
134
+
73
- 根本的な解決方法ことは重々承知の上でようOS側タイミングが由によりBAD_ACCESSになる、メモリが割当てられていか解放されいるか確認する方法はないでしか?
135
+ 今時点特に歪なことはしておらず公式サンプル毛が生えた程度しかしていいので、これを回避すためだけ根本的に全部作替えような対応や、複数の状態管理変数をselfに持たせ歪なフラグコントロールしてま改善とは思いません。