Итак, я расскажу вам, как и почему.
В вашем файле .h
объявите player
ivar с таким свойством
// .h
@interface MyClass : UIViewController
@property (nonatomic, retain) AVAudioPlayer *audioPlayer;
// method signatures
@end
Я назвал его audioPlayer
, просто чтобы быть более точным (это личное предпочтение).
В вашем файле реализации вам нужно synthesize
этот ивар как этот
// .m
@implementation MyClass
@synthesize audioPlayer = _audioPlayer;
// Do some stuff
@end
Это создастподдерживающий ивар и геттер и сеттер с подписями - (void)setAudioPlayer:(AVAudioPlayer *)audioPlayer
и - (AVAudioPlayer *)audioPlayer;
, но на заднем плане они будут манипулировать иваром _audioPlayer
.
Вы упомянули в ответе, что вы пришли из Ruby, это можно сравнить с чем-то вроде этого attr_accessor :audio_player
, но в Objective-C он создает сеттеры и геттеры, которые могут иметь дело с управлением памятью в зависимости от того, передаете ли вы assign/retain/copy
в строку @property
.
Так Apple делает это в большинстве своих примеров, и это означает, что это более понятно, когда вы обращаетесь к ивуру напрямую или проходите через метод получения / установки.
Я бы сейчас изменил ваш -(IBAction)userDidTapButton:(id)sender
, чтобы он выглядел следующим образом
-(IBAction)userDidTapButton:(id)sender
{
[self.audioPlayer stop];
NSURL *soundClip = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:@"clip" ofType:@"mp3"]];
AVAudioPlayer *tmpPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundClip error:nil];;
self.audioPlayer = tmpPlayer;
[tmpPlayer release]; tmpPlayer = nil;
[self.audioPlayer setNumberOfLoops:-1];
[self.audioPlayer play];
}
Я использовал геттеры / сеттеры каждый раз, когда взаимодействовал с audioPlayer ivar.Это означает, что управление памятью осуществляется каждый раз, когда я устанавливаю ivar (например, он освобождает старого игрока и сохраняет нового).Причина, по которой он использует методы получения / установки, заключается в том, что self.audioPlayer
будет скомпилирован для соответствующего вызова следующим образом:
self.audioPlayer; // compiled to -> [self audioPlayer];
self.audioPlayer = tmpPlayer; // compiled to -> [self setAudioPlayer:tmpPlayer];
Теперь, чтобы привести в порядок и сделать правильный метод - (void)dealloc;
, мы должныиспользуйте ивар непосредственно, не проходя через геттер / сеттеры, поэтому я должен использовать _audioPlayer
ивар, который мы синтезировали следующим образом:
#pragma mark - Cleanup
- (void)dealloc
{
[_audioPlayer release];
[super dealloc];
}