简体   繁体   中英

Calling block on a nil object gives exc_bad_access

I came across this scenario where my app was crashing with exec_bad_access when I call a block on a nil object. I was able to fix the issue by add a if condition but I want to know why calling block on a nil object causes 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();
}
*/

Because while blocks are objects, operations on blocks should not be perceived as respecting Objective-C semantics. Just like reading from NULL causes a bad access, invoking a NULL block causes a bad access. This is consistent with the behavior of a function pointer (calling a NULL function pointer crashes your program), and since blocks are available in C and C++ as well, it may have made more sense to use this behavior than a purely Objective-C behavior.

The invoke method is not called through objc_msgSend , which handles and cancels calls to nil objects on Objective-C objects.

Blocks are variables, not methods. You can expect the same things out of a block property than you can out of an int property. They're just like you had some class called Block that had an invoke method on it, and you subclassed it every time you needed it to do something different, except that the compiler does all the subclassing part.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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