繁体   English   中英

Xcode:无法停止从子类播放AVAudioPlayer音乐

[英]Xcode: Unable to stop AVAudioPlayer music playing from sub class

仍然没有解决方案-此处减少了测试案例项目:

http://www.friendlycode.co.uk/assets/Bugfix.zip

我是Xcode / Objective C的新手,已经做了很多研究,但找不到答案。 这里有很多类似的问题,但是没有一个可以帮助我解决这个问题。

文件:

app.h
app.m
Settings.h
Settings.m

我正在播放一些背景音乐,该音乐在通过ViewController.m文件中的ViewDidLoad启动应用程序时开始。

如果尝试触摸“音乐”开关并将其设置为“关闭”,我试图从Settings.m文件中停止此操作。

请参阅下面的代码(已删除了不必要的插座/方法等)

NSLog输出“尝试停止音频”,但音频不会停止。 我想我已经正确引用了ViewController类,所以不确定为什么它不会停止?

app.h

#import <UIKit/UIKit.h>
#import <Social/Social.h>
#import "AVFoundation/AVAudioPlayer.h"

@interface ViewController : GAITrackedViewController <AVAudioPlayerDelegate, UIActionSheetDelegate>
{
    // removed
}

@property (nonatomic, retain) AVAudioPlayer *BackgroundMusicPlayer;

@end

app.m

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Play Background music
    [self PlayBackgroundMusic];
}

-(void)PlayBackgroundMusic
{
    NSString* resourcePath = [[NSBundle mainBundle]
                            pathForResource:@"music-file"
                            ofType:@"aiff"];

    NSLog(@"Path to play: %@", resourcePath);
    NSError* err;

    //Initialize our player pointing to the path to our resource
    _BackgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:
              [NSURL fileURLWithPath:resourcePath] error:&err];

    if( err ){
        //bail!
        NSLog(@"Failed with reason: %@", [err localizedDescription]);
    }
    else{
        //set our delegate and begin playback
        _BackgroundMusicPlayer.delegate = self;
        [_BackgroundMusicPlayer play];
        _BackgroundMusicPlayer.numberOfLoops = -1;
        _BackgroundMusicPlayer.currentTime = 0;
        _BackgroundMusicPlayer.volume = 0.5;
    }
}

Settings.h

#import <UIKit/UIKit.h>
#import "app.h"

@interface Settings : GAITrackedViewController <AVAudioPlayerDelegate, UIActionSheetDelegate>
{
    IBOutlet UIButton *BackButton;
    IBOutlet UISwitch *MusicSwitch;
    IBOutlet UISwitch *SoundFXSwitch;


    // Get instance of ViewController object
    ViewController *home;
}

-(IBAction)BackButton:(id)sender;
-(IBAction)ToggleMusic:(id)sender;
-(IBAction)ToggleSoundFX:(id)sender;


@end

Settings.m

#import "Settings.h"

@interface Settings ()

@end

@implementation Settings

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.

}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

-(IBAction)ToggleMusic:(id)sender {

    // Get instance of ViewController object

    //home = [[ViewController alloc] init];

    if (MusicSwitch.on)
    {
        [home.BackgroundMusicPlayer play];
    }
    else {
       [home.BackgroundMusicPlayer stop];
        NSLog(@"Attempting to stop audio");

    }
}

-(IBAction)ToggleSoundFX:(id)sender {

    if (SoundFXSwitch.on)
    {
    }
    else{

    }
}

-(IBAction)BackButton:(id)sender
{
    [self dismissViewControllerAnimated:YES completion:nil];
}

我认为问题在于ViewController * home。

您的AvAudioPlayer对象位于ViewController接口的app.h中。

但是在您的代码中,您并没有在settings.m中初始化ViewController对象“ home”。 如此有效,您正在尝试访问和停止未创建的播放器。

要访问AVAudioPlayer对象,请在settings.h的viewDidload中添加以下代码。

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    //initialise the audioPlayer object.
    home=[[ViewController alloc] init];
}

在您的Settings.h ,将ViewController属性声明为assign

@interface Settings : GAITrackedViewController <UIActionSheetDelegate>
{
    @property (nonatomic, assign) ViewController *home;
}


-(IBAction)ToggleMusic:(id)sender {

    if (MusicSwitch.on)
    {
        [self.home.BackgroundMusicPlayer play];
    }
    else {

       [self.home.BackgroundMusicPlayer stop];
    }
}

在您的app.m ,将home属性指定为self _BackgroundMusicPlayer.home = self;

-(void)PlayBackgroundMusic
{
    NSString* resourcePath = [[NSBundle mainBundle]
                            pathForResource:@"music-file"
                            ofType:@"aiff"];

    NSLog(@"Path to play: %@", resourcePath);
    NSError* err;

    //Initialize our player pointing to the path to our resource
    _BackgroundMusicPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:
              [NSURL fileURLWithPath:resourcePath] error:&err];

    if( err ){
        //bail!
        NSLog(@"Failed with reason: %@", [err localizedDescription]);
    }
    else{
        //set our delegate and begin playback
        _BackgroundMusicPlayer.delegate = self;
        settingsViewObj.home = self; //recommended after the 'Settings' view allocation code.
        [_BackgroundMusicPlayer play];
        _BackgroundMusicPlayer.numberOfLoops = -1;
        _BackgroundMusicPlayer.currentTime = 0;
        _BackgroundMusicPlayer.volume = 0.5;
    }
}

笔记:

  • 了解有关对象通信的更多信息

  • 阅读有关Objective C编码标准的更多信息

  • 阅读有关类层次结构的更多信息

如果我正确理解了您的代码,则似乎您正在创建初始视图控制器的实例,并尝试停止该实例的音乐播放器属性。 在这种情况下,您要停止的音乐播放器已经停止,因为它是在创建ViewController实例时创建的AVAudioPlayer的单独实例。 为了从第一个视图控制器停止音乐播放器,您可以尝试以下操作:

  1. 在Settings.h文件中,添加一个AVAudioPlayer属性,就像在app.h中一样

     @property (strong, nonatomic) AVAudioPlayer *backgroundMusic; 
  2. 然后,当连接到设置视图控制器时,使用prepareForSegue将音频播放器传递给新控制器:

     - (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender { if([segue.identifier isEqualToString:@"YourSegueName"]) { if([segue.destinationViewController isKindOfClass:[YourSettingsClass class]]) { YourSettingsClass *destination = segue.destinationViewController; destination.backgroundMusic = self.BackgroundMusicPlayer; } } } 
  3. 现在,您应该可以简单地调用[self.backgroundMusic stop]并停止音乐了。

确保在您的应用程序类中#import您的Settings控制器类以在prepareForSegue方法中对其进行访问。

您不能通过导入来访问由它创建的另一个类的对象的实例。在这里,您必须访问相同的对象实例才能停止AVAudioPlayer。

因此,您必须将对象放置在唯一的位置,例如AppDelegate。

尝试在appdelegate.h中声明AVAudioPlayer。

在Appdeleagte.h中

@property (nonatomic, strong) AVAudioPlayer *BackgroundMusicPlayer;

在app.h中,您可以按以下方式访问播放器。

AppDelegate * appDelegate;

//in your viewDidLoad
    appDelegate=[[UIApplication sharedApplication]delegate]; 

//in your PlayBackGroundMusic
       appdelegate.avAudioPlayer=[[AVAudioPlayer alloc] initWithContentsOfURL:
                  [NSURL fileURLWithPath:resourcePath] error:&err];
       [appDelegate.avAudioplayer play];

在您的settings.h中

AppDeleagte * appDelegate;

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    //initialise the audioPlayer object.
    appDelegate=[[UIApplication sharedApplication]delegate]; 


}

您可以通过以下方式停止播放器

[appDelegate.avAudioPlayer stop];

您可以在此处下载固定项目

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM