EXC_BAD_ACCESS KERN_INVALID_ADDRESS 来自一些用户
EXC_BAD_ACCESS KERN_INVALID_ADDRESS from some users
同时,我无法在我的测试设备/模拟器上重现这个问题,我从一些用户那里收到了一些崩溃报告,但不是全部。 EXC_BAD_ACCESS KERN_INVALID_ADDRESS 在这一行。为什么会这样,我可以采取哪些步骤来解决?崩溃报告来自 iOS 14.4.0 和 14.3.0 的用户以及各种设备(iPhone 6s plus,iPhone 8 Plus,iPhone SE(2nd代), iPhone XS, iPhone 7, iPhone 7s, iPhone 11, iPhone 12, iPhone X)
在PageViewController.m
// Voice Recording - Needed as workaround as there is a bug in AudioKit
NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
defaultVoiceRecording,
nil];
NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
// Setup audio session to play through loud speakers
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *error;
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
if(error){
NSLog(@"AVAudioSession Sing the Note error tuner:%@",error);
}
// Setup audio session to play through loud speakers
if (![MenuViewController areHeadphonesPluggedIn]){ // EXC_BAD_ACCESS KERN_INVALID_ADDRESS here
[session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];
if(error)
{
NSLog(@"Error: AudioSession cannot use speakers");
}
}
在MenuViewController.h
+(BOOL)areHeadphonesPluggedIn;
在MenuViewController.m
+(BOOL)areHeadphonesPluggedIn {
@try{
NSArray *availableOutputs = [[AVAudioSession sharedInstance] currentRoute].outputs;
for (AVAudioSessionPortDescription *portDescription in availableOutputs) {
if ([portDescription.portType isEqualToString:AVAudioSessionPortHeadphones]) {
return YES;
}
}
return NO;
}
@catch(id Exception){
return NO;
}
}
+(BOOL)areHeadphonesPluggedIn {
@try{
NSArray *availableOutputs = [[AVAudioSession sharedInstance] currentRoute].outputs;
for (AVAudioSessionPortDescription *portDescription in availableOutputs) {
if ([portDescription.portType isEqualToString:AVAudioSessionPortHeadphones]) {
return YES;
}
}
return NO;
}
@catch(id Exception){
return NO; // Not sure it will work as you exect
}
return NO; // move return here!
}
这个问题归因于堆栈上某处的 'dangling' 指针,在本例中是自动释放数组 pathComponents。需要将其更改为非自动释放数组。
完整解决方案PageViewController.m
// Change from autorelease to normal non-autorelease
NSArray *pathComponentsSN = [[NSArray alloc] initWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],defaultVoiceRecording,nil];
NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponentsSN];
// Setup audio session to play through loud speakers
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *error;
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
if(error){
NSLog(@"AVAudioSession Sing the Note error creating session");
}
// Setup audio session to play through loud speakers
if (![MenuViewController areHeadphonesPluggedIn]){ // Crash logs from this line
[session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];
if(error)
{
NSLog(@"Error: AudioSession cannot use speakers");
}
}
同时,我无法在我的测试设备/模拟器上重现这个问题,我从一些用户那里收到了一些崩溃报告,但不是全部。 EXC_BAD_ACCESS KERN_INVALID_ADDRESS 在这一行。为什么会这样,我可以采取哪些步骤来解决?崩溃报告来自 iOS 14.4.0 和 14.3.0 的用户以及各种设备(iPhone 6s plus,iPhone 8 Plus,iPhone SE(2nd代), iPhone XS, iPhone 7, iPhone 7s, iPhone 11, iPhone 12, iPhone X)
在PageViewController.m
// Voice Recording - Needed as workaround as there is a bug in AudioKit
NSArray *pathComponents = [NSArray arrayWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],
defaultVoiceRecording,
nil];
NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponents];
// Setup audio session to play through loud speakers
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *error;
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
if(error){
NSLog(@"AVAudioSession Sing the Note error tuner:%@",error);
}
// Setup audio session to play through loud speakers
if (![MenuViewController areHeadphonesPluggedIn]){ // EXC_BAD_ACCESS KERN_INVALID_ADDRESS here
[session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];
if(error)
{
NSLog(@"Error: AudioSession cannot use speakers");
}
}
在MenuViewController.h
+(BOOL)areHeadphonesPluggedIn;
在MenuViewController.m
+(BOOL)areHeadphonesPluggedIn {
@try{
NSArray *availableOutputs = [[AVAudioSession sharedInstance] currentRoute].outputs;
for (AVAudioSessionPortDescription *portDescription in availableOutputs) {
if ([portDescription.portType isEqualToString:AVAudioSessionPortHeadphones]) {
return YES;
}
}
return NO;
}
@catch(id Exception){
return NO;
}
}
+(BOOL)areHeadphonesPluggedIn {
@try{
NSArray *availableOutputs = [[AVAudioSession sharedInstance] currentRoute].outputs;
for (AVAudioSessionPortDescription *portDescription in availableOutputs) {
if ([portDescription.portType isEqualToString:AVAudioSessionPortHeadphones]) {
return YES;
}
}
return NO;
}
@catch(id Exception){
return NO; // Not sure it will work as you exect
}
return NO; // move return here!
}
这个问题归因于堆栈上某处的 'dangling' 指针,在本例中是自动释放数组 pathComponents。需要将其更改为非自动释放数组。
完整解决方案PageViewController.m
// Change from autorelease to normal non-autorelease
NSArray *pathComponentsSN = [[NSArray alloc] initWithObjects:
[NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) lastObject],defaultVoiceRecording,nil];
NSURL *outputFileURL = [NSURL fileURLWithPathComponents:pathComponentsSN];
// Setup audio session to play through loud speakers
AVAudioSession *session = [AVAudioSession sharedInstance];
NSError *error;
[session setCategory:AVAudioSessionCategoryPlayAndRecord error:&error];
if(error){
NSLog(@"AVAudioSession Sing the Note error creating session");
}
// Setup audio session to play through loud speakers
if (![MenuViewController areHeadphonesPluggedIn]){ // Crash logs from this line
[session overrideOutputAudioPort:AVAudioSessionPortOverrideSpeaker error:&error];
if(error)
{
NSLog(@"Error: AudioSession cannot use speakers");
}
}