Objective c 自定义Segue不';我不能放声音

Objective c 自定义Segue不';我不能放声音,objective-c,audio,segue,Objective C,Audio,Segue,我做了一个自定义的segue,我希望它在更改视图时播放声音。不幸的是,事实并非如此。方法playSound在视图控制器中使用时效果很好。但我不想在我需要的每个视图控制器中导出它。如何改进代码,以及为什么segue不想播放声音 #import "CustomSegue.h" @import AVFoundation; @interface CustomSegue() @property (nonatomic, strong) AVAudioPlayer *player; @end @imple

我做了一个自定义的segue,我希望它在更改视图时播放声音。不幸的是,事实并非如此。方法playSound在视图控制器中使用时效果很好。但我不想在我需要的每个视图控制器中导出它。如何改进代码,以及为什么segue不想播放声音

#import "CustomSegue.h"
@import AVFoundation;

@interface CustomSegue()
@property (nonatomic, strong) AVAudioPlayer *player;
@end

@implementation CustomSegue
@synthesize player;
- (void) perform
{
    UIViewController *src = (UIViewController *) self.sourceViewController;
    UIViewController *dst = (UIViewController *) self.destinationViewController;

    [UIView transitionWithView:src.navigationController.view duration:0.5
                       options:UIViewAnimationOptionTransitionCrossDissolve
                    animations:^{
                        [src.navigationController pushViewController:dst animated:NO];
                    }
                    completion:NULL];
    [self playSound];
}

- (void) playSound
{
    int r = arc4random_uniform(7) + 1;

    NSURL *soundUrl = [NSURL fileURLWithPath:[[NSBundle mainBundle] pathForResource:[NSString stringWithFormat:@"%i", r] ofType:@"caf"]];
    self.player = [[AVAudioPlayer alloc] initWithContentsOfURL:soundUrl error:nil];

    [self.player prepareToPlay];
    [self.player play];
}

我打赌你的自定义segue在声音有机会播放之前就发布了,你的音频播放器也随之发布。在执行
-perform
后立即解除分配

您需要做的是将音频播放器保留更长时间。一种方法是从一个对象添加对AVAudioPlayer的(强)引用,该对象至少在声音播放的时间内不会被释放。例如,将播放器放置在应用程序代理中,只要应用程序正在运行,该代理就会一直存在

尝试将
player
属性和
-playsound
方法移动到应用程序代理中。该属性的外观应类似于:

@property (strong, nonatomic) AVAudioPlayer *player;
MyAppDelegate *appDelegate = (MyAppDelegate*)[[UIApplication sharedApplication] delegate];
[appDelegate playsound];
然后,在此序列中,代替
[自播放声音]通过以下方式调用应用程序代理:

@property (strong, nonatomic) AVAudioPlayer *player;
MyAppDelegate *appDelegate = (MyAppDelegate*)[[UIApplication sharedApplication] delegate];
[appDelegate playsound];

您的声音无法播放,因为segue对象在segue完成执行后立即释放。@rdelmar,谢谢您的回答。所以,我没有办法做这样的自定义segue?好吧,你可以在源代码视图控制器中为segue创建一个强属性(在prepareForSegue中),但你需要在每个控制器中都这样做,所以我认为这不是一个比将playSound方法复制到任何需要它的控制器中更好的解决方案。@rdelmar,我害怕那个答案。无论如何,谢谢。我不确定这是不是最好的方法,但你可以在你的segue类中创建一个计时器。计时器保留对其目标的强引用,因此在计时器失效之前,segue对象不会被释放。当声音播放完毕时,您应该使计时器无效(您可以在委托方法audioPlayerDidFinishPlaying:successfully:中执行此操作)。