在nil对象上调用块会给出exc_bad_access

时间:2015-01-07 16:47:47

标签: ios objective-c objective-c-blocks

我遇到了这个场景,当我在一个nil对象上调用一个块时,我的应用程序崩溃了exec_bad_access。我能够通过添加if条件来解决问题,但我想知道为什么在nil对象上调用块会导致bad_access?

@interface CustomView :UIView

@property (nonatomic, strong) UIImage* sourceImage;
@property (nonatomic, copy) void(^doneSwipingBlock)();

- (void)testMethod;

@end

//Another Class
//Sample Code (this is not the actual code but shows the crash 
CustomView view = nil;
view.sourceImage = [UIImage imageNamed:@"image.png"]; //no error as view is nil
[view testMethod]; //no error as view is nil
view.doneSwipingBlock();  //Crashes here

/*
//This works fine
if (view.doneSwipingBlock) {
    view.doneSwipingBlock();
}
*/

1 个答案:

答案 0 :(得分:6)

因为虽然块是对象,但块上的操作不应被视为遵循Objective-C语义。就像从NULL读取导致访问不良一样,调用NULL块会导致访问不良。这与函数指针的行为一致(调用NULL函数指针会使程序崩溃),并且由于块在C和C ++中也可用,因此使用此行为比纯粹的Objective-C行为更有意义。

不通过objc_msgSend调用invoke方法,int处理和取消对Objective-C对象上的nil对象的调用。

块是变量,而不是方法。您可以从块属性中获得与Block属性相同的内容。他们就像你有一个名为invoke的类,它上面有一个{{1}}方法,每次你需要它做一些不同的事情时你都会将它子类化,除了编译器完成所有的操作子类化部分。