简体   繁体   English

Objective-C中的EXC_BAD_ACCESS错误

[英]EXC_BAD_ACCESS error in Objective-C

I'm trying to write a simple iOS program that will notify when headphones are plugged/unplugged. 我正在尝试编写一个简单的iOS程序,它会在插入/拔出耳机时通知。 I'm very new to Objective-C and iOS , and a lot of this code was written by somebody else and I'm now trying to adapt it so I'm having issues figuring out this problem. 我是Objective-CiOS新手,很多代码都是由其他人编写的,我现在正在尝试调整它,所以我遇到了解决这个问题的问题。 The code is here: 代码在这里:

AppDelegate.m AppDelegate.m

#import "AppDelegate.h"

@implementation AppDelegate

static void onHeadsetChange(void *, AudioServicesPropertyID, UInt32, const void *);

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    self.headsetOnHandler = self.headsetOffHandler = ^{};
    NSLog(@"%lu", AudioSessionInitialize(NULL, NULL, NULL, NULL));
    NSLog(@"%lu", AudioSessionSetActive(true));
    NSLog(@"%lu", AudioSessionAddPropertyListener(kAudioSessionProperty_AudioRouteChange, &onHeadsetChange, (__bridge void *)self));
    return YES;
}

static void onHeadsetChange(void *inUserData, AudioSessionPropertyID inPropertyID, UInt32 inPropertyValueSize, const void *inPropertyValue) {
    if (inPropertyID != kAudioSessionProperty_AudioRouteChange) return;
    NSLog(@"The headset changed");
    AppDelegate *const delegate = (__bridge AppDelegate *)inUserData;

    const CFDictionaryRef routeChangeDictionary = inPropertyValue;
    const CFNumberRef routeChangeReasonRef = CFDictionaryGetValue(routeChangeDictionary, CFSTR(kAudioSession_AudioRouteChangeKey_Reason));
    SInt32 routeChangeReason;
    CFNumberGetValue(routeChangeReasonRef, kCFNumberSInt32Type, &routeChangeReason);
    switch (routeChangeReason) {
        case kAudioSessionRouteChangeReason_NewDeviceAvailable:
            //NSLog([delegate description]);
            [delegate headsetOnHandler];
            break;
        case kAudioSessionRouteChangeReason_OldDeviceUnavailable:
            [delegate headsetOffHandler];
            break;
        default:
            break;
    }
}
@end

ViewController.m ViewController.m

#import "ViewController.h"

@implementation ViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view.
    self.view.backgroundColor = [UIColor redColor];
    AppDelegate *delegate = (AppDelegate *)([UIApplication sharedApplication].delegate);
    delegate.headsetOnHandler = ^{ self.view.backgroundColor = [UIColor greenColor];};
    delegate.headsetOffHandler = ^{ self.view.backgroundColor = [UIColor redColor];};
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

I'm getting the EXC_BAD_ACCESS error, code=1 at [delegate headsetOnHandler] and [delegate headsetOffHandler] . EXC_BAD_ACCESS error, code=1 at [delegate headsetOnHandler] and [delegate headsetOffHandler]收到EXC_BAD_ACCESS error, code=1 at [delegate headsetOnHandler] and [delegate headsetOffHandler] If I need to include the .h files for this to make sense, I will, and if there's anything else I'm missing please let me know. 如果我需要包含.h文件才有意义,我会,如果还有什么我想念的,请告诉我。

EDIT: I've added in declarations that people thought should be added: 编辑:我添加了人们认为应该添加的声明:

@property (readwrite, assign) void (^headsetOnHandler)(void);
@property (readwrite, assign) void (^headsetOffHandler)(void);

How is the headsetOnHandler and headsetOffHandler properties declared? 如何声明headsetOnHandlerheadsetOffHandler属性?

If it is assign or retain , that is likely the source of your problem. 如果是assignretain ,则可能是您的问题的根源。 Since they are blocks, it needs to be copy (even, in certain cases, under ARC). 由于它们是块,因此需要copy (甚至在某些情况下,在ARC下)。 If they are atomic and retain , then your getter will call, effectively, [[block retain] autorelease] in the getter, which would explain your crash. 如果它们是atomicretain ,那么你的getter将有效地调用[[block retain] autorelease]在getter中,这可以解释你的崩溃。

A bit of a long shot. 有点远射。

  • when you have a crash, always post the backtrace 当你遇到崩溃时, 总是发布回溯

  • when you know the line of code the crash is on, always post the variable declarations of any variables on that line 当你知道崩溃所在的代码行时, 总是在该行上发布任何变量的变量声明

Note that ARC will change this behavior a bit, automatically handling the blocks in some cases, but -- IIRC -- you would still need to copy them in this case. 请注意,ARC会稍微改变这种行为,在某些情况下会自动处理块,但是 - IIRC - 在这种情况下你仍然需要copy它们。

Here's a good post on EXC_BAD_ACCESS by Ray Wenderlich. 这是Ray Wenderlich关于EXC_BAD_ACCESS的好帖子。

http://www.raywenderlich.com/10209/my-app-crashed-now-what-part-1 http://www.raywenderlich.com/10209/my-app-crashed-now-what-part-1

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM