私の目標は、メイン スレッド/GUI の速度を落とさずに、バックグラウンドで一時停止して一連のサウンドを再生することです。
Time Profiler Instrument を使用してコードを実行すると、次のようになります。AudioStateMachine init は GCD を使用して別のスレッドにディスパッチされますが、AudioStateMachine の他のメソッドはメイン スレッドで実行されます。メインで実行しないようにするには、AudioStateMachine のすべてのメソッドが必要です。
Running Time Self Symbol Name
87.0ms 8.7% 0.0 Main Thread 0x8531c
84.0ms 8.4% 0.0 start
84.0ms 8.4% 83.0 main
1.0ms 0.1% 0.0 -[AudioStateMachine audioPlayerDidFinishPlaying:successfully:]
1.0ms 0.1% 1.0 -[AudioStateMachine play:]
1.0ms 0.1% 1.0 -[AudioStateMachine states]
1.0ms 0.1% 1.0 -[AudTabController viewDidLoad]
1.0ms 0.1% 1.0 instruments_notifier
4.0ms 0.4% 0.0 _dispatch_worker_thread2 0x85371
4.0ms 0.4% 1.0 __38-[ScreeningViewController viewDidLoad]_block_invoke
3.0ms 0.3% 0.0 -[AudioStateMachine init]
オーディオ バックグラウンド タスクをディスパッチするビュー コントローラーのコード:
controller.h
@interface ScreeningViewController : UIViewController {
UIButton *okButton;
UIProgressView *bar;
AudioStateMachine *test;
}
@property(nonatomic, strong) UIButton *okButton;
@property(nonatomic, strong) UIProgressView *bar;
-(IBAction)okPressed:(id)sender;
@end
コントローラー.m
@implementation ScreeningViewController
@synthesize okButton;
@synthesize bar;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
return self;
}
-(void)okPressed:(id) sender{
NSLog(@"OK button pressed");
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor whiteColor];
//kick off state machine
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
test = [[AudioStateMachine alloc] init];
});
}
@end
そして AudioStateMachine.h:
@interface AudioStateMachine : NSObject <AVAudioPlayerDelegate>
{
AVAudioPlayer *player;
NSArray *soundList;
int index;
}
@property(nonatomic, strong) AVAudioPlayer *player;
@property(nonatomic, strong) NSArray *soundList;
- (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag;
- (id)init;
- (void)play:(int)i;
@end
そして.m:
@implementation AudioStateMachine
@synthesize player, soundList;
-(id)init
{
if ((self = [super init]))
{
soundList = [[NSArray alloc] initWithObjects:@"1",@"2",@"3",@"4",nil];
index = 0;
[self play:index];
}
else
NSLog(@"Error initializing AudioStateMachine");
return self;
}
-(void) play:(int)i
{
NSError *error;
player = [[AVAudioPlayer alloc] initWithContentsOfURL:[[NSURL alloc] initFileURLWithPath:[[NSBundle mainBundle] pathForResource:[soundList objectAtIndex:i] ofType:@"wav"]] error:&error];
player.delegate = self;
[player prepareToPlay];
[player play];
}
-(void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag
{
[NSThread sleepForTimeInterval:1.5];
if (index < soundList.count) {
index++;
[NSThread sleepForTimeInterval:1.0];
[self play:index];
} else {
NSLog(@"Reached end of sound list.");//reached end of queue
}
}
@end
助けていただければ幸いです。