为块处理程序踩 "EXC_BAD_ACCESS KERN_INVALID_ADDRESS"
Stomped on a "EXC_BAD_ACCESS KERN_INVALID_ADDRESS" for a block handler
我有生产代码,我发现它偶尔会因块处理程序上的 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
我的class中的调用代码定义为:
@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可以调用多次
- 应用程序在后台唤醒,可以创建。
任何指点,帮助高度赞赏..我只是不能指责这段代码并说那是错误的。请帮忙!
两个对我来说有点奇怪的提示:
首先:为什么要在它自己的块中将对象设置为 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];
}
我也不明白代码的确切作用和原因。我相信对于您在此 class.
中取得的成就,会有一个更容易和更好维护的解决方案如果你想了解更多关于EXC_BAD_ACCESS的信息,那么你可以关闭NSZombies。在 Xcode 中,转到 Product > Scheme > Edit Scheme 并选中 Enable Zombie Objects.