AVAudioPlayer实例的过度发布

时间:2019-03-21 21:34:46

标签: ios objective-c crash avaudioplayer crashlytics

很难找到这个。生产应用程序间歇性崩溃(约2%的用户)。这是一个纸牌游戏,因此很多时候都在玩纸牌。每当您点击卡时,它都会发出声音。崩溃似乎是随机发生的,但是我可以通过轻按卡一会儿然后随机重现来重现。

不可能可靠地复制,但是在使用乐器/僵尸进行了长时间的讨论之后,我看到Zombie对象是

<apex:page docType="html-5.0" standardController="Opportunity" extensions="Controller_soqlQuery" tabStyle="Opportunity">



   <apex:pageblock >
     <apex:pageBlockSection title="Subscription Statistics"  columns="2">
       
           <apex:outputField value="{!Opportunity.Account.Contacts_Engaged__c}"/>                 
           <apex:outputField value="{!Opportunity.Account.Opportunities_Medical__c }"/>
           <apex:outputfield value="{!Opportunity.Account.Opportunities_Non_Medical__c }"/>
           <apex:outputField value="{!Opportunity.Account.Prec_Medical__c }"/>
           <apex:outputfield label="# Medical Opps" value="{!MedOppsCount}" />
            
        
     </apex:pageBlockSection>
    </apex:pageblock>
        
       
          
 
               
     
</apex:page>
对象。它是一个简单的纸牌游戏应用程序(未使用SK或任何其他游戏框架-所有UIKit /普通Objective C来完成)。我正在使用<apex:page docType="html-5.0" standardController="Opportunity" extensions="Controller_soqlQuery" tabStyle="Opportunity"> <apex:pageblock > <apex:pageBlockSection title="Subscription Statistics" columns="2"> <apex:outputField value="{!Opportunity.Account.Contacts_Engaged__c}"/> <apex:outputField value="{!Opportunity.Account.Opportunities_Medical__c }"/> <apex:outputfield value="{!Opportunity.Account.Opportunities_Non_Medical__c }"/> <apex:outputField value="{!Opportunity.Account.Prec_Medical__c }"/> <apex:outputfield label="# Medical Opps" value="{!MedOppsCount}" /> </apex:pageBlockSection> </apex:pageblock> </apex:page>的非常简单的实现。下面的所有详细信息。

堆栈跟踪:

AVAudioPlayer

AppDelegate.m AVAudioPlayer

Crashed: com.apple.main-thread
0  libobjc.A.dylib                0x206270d70 objc_msgSend + 16
1  Foundation                     0x207b3d42c __NSThreadPerformPerform + 336
2  CoreFoundation                 0x20701a0e0 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
3  CoreFoundation                 0x20701a060 __CFRunLoopDoSource0 + 88
4  CoreFoundation                 0x207019944 __CFRunLoopDoSources0 + 176
5  CoreFoundation                 0x207014810 __CFRunLoopRun + 1040
6  CoreFoundation                 0x2070140e0 CFRunLoopRunSpecific + 436
7  GraphicsServices               0x20928d584 GSEventRunModal + 100
8  UIKitCore                      0x2343a8c00 UIApplicationMain + 212
9  <app name>                      0x1007930f0 main (main.m:14)
10 libdyld.dylib                  0x206ad2bb4 start + 4

ViewController.h

didFinishLaunchingWithOptions

ViewController.m

[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:nil];
BOOL success = [[AVAudioSession sharedInstance] setActive:YES error:nil];

AVAudioPlayer参考历史记录 enter image description here

@property (strong, nonatomic) AVAudioPlayer *audioPlayer; 是调用-(void) playSound:(NSString *) strSoundName { NSString *fileName = @"Move_1"; NSString *soundFilePath = [[NSBundle mainBundle] pathForResource:fileName ofType:@"aif"]; NSURL *soundFileURL = [NSURL fileURLWithPath:soundFilePath]; float volume = 0.5; self.audioPlayer = [[AVAudioPlayer alloc] initWithContentsOfURL:soundFileURL error:nil]; [self.audioPlayer setVolume:volume]; [self.audioPlayer play]; }

的方法

2 个答案:

答案 0 :(得分:1)

您在这里进行了非常出色的调试工作。诸如此类的内存​​管理/堆损坏错误使大多数人大跌眼镜。

但是,在Instruments跟踪中有一个需要调查的线索:performSelector调用之后,僵尸就出现了。这使我认为performSelector调用的代码中引用了指向您的视图控制器或AVAudioPlayer实例本身的指针。由于这段代码是在取消分配视图控制器之后运行的,因此可以得到悬挂指针。

对于初学者,我将更仔细地研究handleTap:::的工作。您要在此处调用performSelector吗?而且,如果是这样,请仔细查看您正在使用的实例。如果不是,请检查您在其他地方使用performSelector的情况,以查看是否可以将普通指针捕获到视图控制器或AVAudioPlayer实例。

答案 1 :(得分:0)

永远无法弄清楚它为什么随机崩溃。

但是,我们能够通过在AVAudioPlayer中初始化viewDidLoad一次,然后以该方法调用play来解决此问题(而不是每次我们想播放声音)。