2014-02-18 6 views
0

Это может быть основной вопрос, но я новичок в Cocoa и Objective-C и OOP в целом, и я не смог найти ответ на это в любом месте.Могу ли я создать один объект, доступный разными способами?

В приложении, которое я пишу, я хочу воспроизводить звуковой файл всякий раз, когда пользователь нажимает определенную кнопку. Я использую NSSound для этого, и у меня нет проблем с его внедрением. Проблема заключается в том, я только знаю, как сделать это путем создания нового NSSound объекта каждый раз при нажатии кнопки:

- (IBAction)playSound:(id)sender { 
    NSSound *sound = [[NSSound alloc] initWithContentsOfFile:kSoundFilePath byReference:YES]; 
    [sound play]; 
} 

Это вопрос для меня, потому что, если пользователь нажимает на кнопку несколько раз до того, как файл завершения воспроизведения , он создаст новые экземпляры NSSound, и все они будут играть друг над другом, чего я не хочу. Есть ли способ, которым я могу создать объект NSSound вне этого метода, и использовать метод IBAction для проверки кнопки, чтобы увидеть, играет ли NSSound, прежде чем говорить ему снова играть?

+0

Как насчет sharedInstance/singleton? – Larme

+0

Это не очень хороший подход. Он хочет сохранить переменную после ее создания, а не разрешать только один звуковой объект. – SevenBits

ответ

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 

Вы также можете сделать это таким образом. EDIT: Как указано в комментариях, есть некоторые проблемы при использовании глобальной переменной в его моде. Если вы когда-либо будет создавать несколько экземпляров этого класса, вам может быть лучше использовать 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 

Лично я использую первый способ, потому что он делает более понятным с точки зрения программирования то, что ваш класс владеет созданным объектом. Хотя второй способ является законным, менее понятно, где объект принадлежит ... это может быть локальная переменная в области метода или что-то еще. I настоятельно рекомендую первым способом, но в интересах образования вы должны знать обо всех возможных путях.

+0

В дополнение к созданию свойства вы можете проверить, продолжает ли звук воспроизводиться, когда действие отправляется с (BOOL) isPlaying – Cory

+0

Очень верно, но я не буду изменять код ... Я думаю, что это выходит за рамки вопрос. – SevenBits

+0

-1 потому что это не решает проблему автора. То же самое, что и до создания нового объекта NSSound и воспроизведения. Вы сохраняете его для свойства, но сохраненный объект никогда не используется. – Avt

0

вверх при объявлении вашего класса, который должен выглядеть примерно так:

@implementation MyViewController 

Добавить это:

@implementation MyViewController { 
    NSSound* sound; 
} 

Тогда в viewDidLoad:

sound = [[NSSound alloc] initWithContentsOfFile:kSoundFilePath byReference:YES]; 

И, наконец:

- (IBAction)playSound:(id)sender { 
    [sound play]; 
} 
Смежные вопросы