必须从ViewController类实例化AVAudioPlayer吗?

时间:2015-07-02 09:08:19

标签: objective-c

我希望有人可以提供帮助,因为我是iOS / Objective C的新手并且非常困惑。我尝试使用AVAudioPlayer播放一个简单的声音,如下所示:

NSString *path = [[NSBundle mainBundle] pathForResource:@"soundFile" ofType:@"wav"];
NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: path];
self.player=[[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:NULL];
[self.player play];

我正在使用ARC所以我也在我的.h文件中,以下引用了我的播放器,以便ARC不会过早地释放我的播放器:

@property (nonatomic, strong) AVAudioPlayer *player;

这段代码工作得很好并且播放我的声音提供我从ViewController或我的应用程序的AppDelegate运行此代码。

但是,如果我剪切并粘贴这个相同的代码,加上所有必要的#includes和@property,并将它们添加到同一个应用程序中的另一个类但不是ViewController,并在那里调用代码,那么没有错误是举起但没有播放声音。

这是在同一个类上调用的完全相同的代码? 为什么不起作用?

我已经看过并寻找过类似的帖子,但我似乎无处可寻。非常感谢你能帮助我 - 非常感谢。

澄清问题 - 这里是我如何在另一个类上调用此代码说我命名为Audio Tester的类,我会在AppDelate中写一下说

#import "AppDelegate.h"
#import "AudioTester.h"

@interface AppDelegate ()

@end

@implementation AppDelegate

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {

  AudioTester * tester = [[AudioTester alloc]init];
  [tester playAudio];
}

其中AudioTester playAudio被定义为

#import "AudioTester.h"

@implementation AudioTester

-(void) playAudio {
    NSString *path = [[NSBundle mainBundle] pathForResource:@"soundFile" ofType:@"wav"];
    NSURL *fileURL = [[NSURL alloc] initFileURLWithPath: path];
    self.player=[[AVAudioPlayer alloc] initWithContentsOfURL:fileURL error:NULL];
    [self.player play];
}
@end

使用AudioTester.h如下

#import <Cocoa/Cocoa.h>
#import <Foundation/Foundation.h>
#import <AVFoundation/AVFoundation.h>

@interface AudioTester : NSObject
@property (nonatomic, strong) AVAudioPlayer *player;
-(void) playAudio;

@end

单步执行此代码,它被调用得很好,但它不播放声音?

如果你能提供帮助,那将非常感激。我完全难过了。

1 个答案:

答案 0 :(得分:0)

关于您的代码的一些概念性解释:

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification {
   AudioTester * tester = [[AudioTester alloc]init];
   [tester playAudio];
}

1

如果你使用ARC那么实例在范围用完后不会保持活动状态,因此tester对象将立即释放,因此在你的情况下,对象被释放在它可以做任何事情之前 - 这就是为什么你听不到任何噪音或声音的原因。

如果您希望将tester实例独立于您当前所在的范围内,则需要创建例如属于范围之外的财产;你可以把它放到类扩展中,例如:

@interface AppDelegate ()

// ...

@property (nonatomic, strong, nullable) AVAudioPlayer * tester;

// ...

@end

2

我们没有将这样的内容放到AppDelegate.m文件中,app委托类基本上处理与app相关的事件,如启动,终止等...简要地说,全局和重大事件应用程序在运行时的生命周期。

您可以在official docs

中详细了解其用途

3

您可以故意使用–applicationDidFinishLaunching:方法来启动您的应用,但我觉得有必要提一下您可能希望将所有内容都放在方法–application:didFinishLaunchingWithOptions:中。

您可以在the same documentation中了解有关初始程序的更多信息。

TL; DR

原始问题的答案: NO ,一般可以在任何类型的类的任何其他实例中引入和实例化类,但是您需要担心保持对象的活动时间长因为你想使用它。