Как правильно выпустить звук? [AVAudioPlayer] - PullRequest
1 голос
/ 10 января 2011

Мне нужна помощь с моим iOS приложением ^^ ,.Я хочу знать, правильно ли я выпускаю AVAudioPlayer.

MyViewController.h

#import <UIKit/UIKit.h>

@interface MyViewController : UIViewController
{
    NSString    *Path;
}

- (IBAction)Playsound;

@end

MyViewController.m

#import <AVFoundation/AVAudioPlayer.h>
#import "MyViewController.h"

@implementation MyViewController

AVAudioPlayer *Media;

- (IBAction)Playsound
{
   Path = [[NSBundle mainBundle] pathForResource:@"Sound" ofType:@"wav"];
   Media = [[AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:Path] error:NULL];
   [Media play];
}

- (void)dealloc
{
   [Media release];
   [super viewDidUnload];
}

@end

Ответы [ 2 ]

3 голосов
/ 10 января 2011

Я думаю, что способ, которым вы реализовали свое решение, мог бы быть лучше, и понимание того, почему это поможет вам учиться.

Во-первых, в Objective-C (по крайней мере, Cocoa и Cocoa Touch) принято именовать переменныеи имена методов, начинающиеся со строчной буквы.Например, ваша переменная "Media" должна быть "media", а ваш метод "PlaySound" должен быть "playSound".

Во-вторых, ваша переменная "media" объявлена ​​как глобальная переменная, и было бы лучшеобъявите его как переменную экземпляра в @interface в вашем файле MyViewController.h.Таким образом, каждый экземпляр MyViewController будет иметь переменную экземпляра, называемую «media», которая лучше соответствует объектно-ориентированной концепции инкапсуляции.Лично я бы назвал переменную «player», потому что мне кажется, что она описывает, какая переменная лучше (с этого момента я буду использовать «player»).

В-третьих, если ваш «playSound»всегда собираясь воспроизводить тот же звук, что и у вас, может быть лучше перенести выделение объекта «media» на метод «init ...» (например, initWithNibName: bundle: method).Таким образом, вы создаете экземпляр объекта только один раз, а не каждый раз, когда вызывается ваш метод playSound (я предполагаю, что он может вызываться несколько раз).Ваш метод "playSound" должен был бы вызвать только [player play].Таким образом, на самом деле нет никакой причины иметь ваш путь в качестве переменной экземпляра.

Наконец, если вы делаете вещи, как описано выше, тогда имеет смысл вызывать [player release] в методе dealloc.Метод dealloc вызывается, когда экземпляр класса освобождается, и он освобождает принадлежащий ему экземпляр «player».

Вот как будут выглядеть мои изменения.

MyViewController.h

#import <UIKit/UIKit.h>

@class AVAudioPlayer;

@interface MyViewController : UIViewController
{
    AVAudioPlayer *player;
}

- (IBAction)playSound;

@end

MyViewController.m

#import <AVFoundation/AVAudioPlayer.h>
#import "MyViewController.h"

@implementation MyViewController

- (id)initWithNibName:(NSString*)nibName bundle:(NSBundle*)nibBundleOrNil
{
    if (self = [super initWithNibName:nibName bundle:nibBundleOrNil]) {
        NSString *filePath = [[NSBundle mainBundle] pathForResource:@"Sound" ofType:@"wav"];
        player = [AVAudioPlayer alloc] initWithContentsOfURL:[NSURL fileURLWithPath:filePath] error:NULL];
    }
    return self;
}

- (IBAction)playSound
{
   [player play];
}

- (void)dealloc
{
   [player release];
   [super dealloc];
}

@end
0 голосов
/ 10 января 2011

Лучший способ думать о памяти в Какао - «Я выпустил что-нибудь, что у меня есть?».В приведенном вами примере вы создаете право собственности на переменную 'Media', выделяя ее память, тем самым создавая контракт между вашим классом и этим распределением, чтобы освободить ваше владение объектом, когда вы закончите с ним.

Другими словами, когда вы создали этот объект, он имел счет сохранения 1, что означает, что вы являетесь его владельцем, и вам необходимо отказаться от права собственности на него после того, как с ним покончено.Это не обязательно означает, что объект будет немедленно освобожден;парадигма памяти Какао означает, что если вы когда-либо получали объект, который не создавали, и все же нуждались в нем, чтобы «остаться в живых» достаточно времени, чтобы вы могли с ним работать, вы вызываете «сохранить», а затем «отпустить», когда вызакончил с этим.

В добавление к вышесказанному, понятие «autorelease»;pathForResource: метод передает вам право собственности на объект при возврате - другими словами, после создания объекта он сам отказывается от владения, вызывая autorelease для объекта перед его возвратом, поэтому на ваш класс возлагается ответственность за решение, что именноделать с ним (вы можете «сохранить» его, затем потребовать «релиз» где-то позже, или просто использовать его, пока он не будет освобожден).

Я бы рекомендовал прочитать Руководство Apple по памяти;как только вы освоите концепции, вы получите: Руководство по программированию управления памятью

...