这可能是一个基本问题,但我是Cocoa,Objective-C和OOP的新手,我无法在任何地方找到答案。
在我正在编写的应用程序中,我想在用户按下特定按钮时播放声音文件。我正在使用NSSound,并没有实现它的问题。问题是,每次按下按钮时,我只知道如何通过创建一个新的NSSound对象来实现它:
- (IBAction)playSound:(id)sender {
NSSound *sound = [[NSSound alloc] initWithContentsOfFile:kSoundFilePath byReference:YES];
[sound play];
}
这对我来说是一个问题,因为如果用户在文件播放完毕之前反复单击按钮,它将创建NSSound的新实例,并且它们将全部在彼此之上播放,这是我不想要的。有没有办法可以在该方法之外创建NSSound对象,并在按钮检查之前检查NSSound是否正在播放,然后告诉它再次播放?
答案 0 :(得分:1)
Yessir。这可以通过几种方式完成。一种简单的方法是使用私有财产:
/* these are in the SAME FILE */
@interface MyClass ()
@property (nonatomic, retain) NSSound *sound;
@end
@implementation MyClass
- (IBAction)playSound:(id)sender {
self.sound = [[NSSound alloc] initWithContentsOfFile:kSoundFilePath byReference:YES];
[self.sound play];
}
@end
您也可以这样做。 编辑:正如Avt在评论中所说,在他的时尚中使用全局变量时存在一些问题。如果您曾将创建此类的多个实例,那么最好使用singleton design pattern。要解释一下,这里是an article by the venerable Mattt Thompson。
@implementation MyClass
NSSound *sound;
...
- (IBAction)playSound:(id)sender {
sound = [[NSSound alloc] initWithContentsOfFile:kSoundFilePath byReference:YES];
[sound play];
}
@end
我个人使用第一种方式,因为从编程的角度来看,它更清楚你的类拥有创建的对象。虽然第二种方式是合法的,但是对象所属的位置不太清楚......它可能是方法范围内的局部变量,或者其他东西。我强烈推荐第一种方式,但为了教育,你应该了解所有可能的方法。
答案 1 :(得分:0)
在你的班级宣言中,看起来应该是这样的:
@implementation MyViewController
添加:
@implementation MyViewController {
NSSound* sound;
}
然后在viewDidLoad中:
sound = [[NSSound alloc] initWithContentsOfFile:kSoundFilePath byReference:YES];
最后:
- (IBAction)playSound:(id)sender {
[sound play];
}