踩在" EXC_BAD_ACCESS KERN_INVALID_ADDRESS"对于块处理程序

时间:2016-09-21 10:38:54

标签: ios crash objective-c-blocks

我有生产代码,我发现它在块处理程序中偶尔会崩溃EXC_BAD_ACCESS KERN_INVALID_ADDRESS。我可以为我的生活弄清楚我的代码有什么问题。我试图重现这一点,并且无法在我的受控环境中重现。这是剥离和清理的代码:

代码段:

typedef void (^TestCallBackHandler)(NSString* location, NSError* error);

@interface _TestClass : NSObject

@property (nonatomic, copy) TestCallBackHandler handler;
@property (nonatomic, strong)NSTimer *endTimer;

- (void)fireOneOff:(TestCallBackHandler)handler;

@end

@implementation _TestClass

- (void)fireOneOff:(TestCallBackHandler)handler
{
    _handler = handler;

    NSLog(@"** New %p %@ Incoming %p, %@ Ours %p %@",self,self,handler, handler, _handler, _handler);
    _endTimer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(_stop) userInfo:nil repeats:NO];
}

- (void)dealloc
{
    NSLog(@"%@ Dealloced",self);
    _handler = nil;
}

- (void)_stop
{
    NSLog(@"** Stopping ? %@",self);
    if (_handler)
        _handler([NSString stringWithFormat:@"Hello %@",[NSDate date]], nil);
}

@end

我班级的调用代码定义为:

@property (nonatomic, strong)_TestClass *testClassInstance;

并且这样调用:

- (void)startTestClass {
    _testClassInstance =  [[_TestClass alloc] init];
    [_testClassInstance fireOneOff:^(NSString *newString, NSError *error) {
    NSLog(@"Got new String! %@",newString);
    _testClassInstance = nil;
}];
}

很少有事情需要注意:

  • 可以多次调用startTestClass
  • 应用程序在后台唤醒,可以创建。

任何指针,帮助高度赞赏..我只是不能指责这个代码,并说这是错的。请帮忙!

2 个答案:

答案 0 :(得分:1)

对我来说有点奇怪的两个提示:

首先:你为什么要把对象设置为nil在它自己的块中。

- (void)startTestClass {
        _testClassInstance =  [[_TestClass alloc] init];
        [_testClassInstance fireOneOff:^(NSString *newString, NSError *error) {
        NSLog(@"Got new String! %@",newString);
        _testClassInstance = nil;
    }];
}

其次,您的对象可能已经被释放,NSTimer正在尝试在发布对象上执行方法

- (void)fireOneOff:(TestCallBackHandler)handler
{
    _handler = handler;

    NSLog(@"** New %p %@ Incoming %p, %@ Ours %p %@",self,self,handler, handler, _handler, _handler);
    _endTimer = [NSTimer scheduledTimerWithTimeInterval:5 target:self selector:@selector(_stop) userInfo:nil repeats:NO];
}

我也不知道代码的确切原因和原因。我相信对于您在本课程中取得的成就,会有一个更简单,更好的可维护解决方案。

答案 1 :(得分:1)

如果您想了解有关EXC_BAD_ACCESS的更多信息,那么您可以转向NSZombies。在Xcode中转到产品>方案>编辑方案并设置选中启用僵尸对象