简体   繁体   中英

objective-c callback function errors with EXC_BAD_ACCESS

I have the following callback function:

void(^getImageCallback)(BOOL success,  UIImage *image , NSError *error);

- (void)getRemoteImageWithObjectId:(NSString *)objectId andType:(NSString *)type andSaveLocal:(BOOL)saveLocal withCallback:(GAGetImageCompletionBlock)callback{
    getImageCallback = callback;

    [self getRemoteImageWithObjectId:objectId andType:type shouldSaveLocal:saveLocal];

}

- (void)getRemoteImageWithObjectId:(NSString *)objectId andType:(NSString *)type shouldSaveLocal:(BOOL)saveLocal{

    UIImage *image = [UIImage imageNamed:@"running.png"];
    getImageCallback(YES, image, nil); //it errors out here
}

My app crashes here with error: Thread 1: EXC_BAD_ACCESS (code=1, address=0x10)

Does anyone know why this might happen?

You might call the 2nd getRemoteImageWithObjectId method instead of the 1st getRemoteImageWithObjectId method. So getImageCallback variable was nil at that time. The reason of EXC_BAD_ACCESS (code=1, address=0x10) might be calling the nil getImageCallback block.

For example, if you compile and execute the following Objective-C code on 64bit environment, you got the exactly same EXC_BAD_ACCESS with address=0x10.

void (^block)() = 0;
block();

You can double check this code in C++ with clang -rewrite-objc option. This Objective-C code was compiled as the following C++ code.

struct __block_impl {
    void *isa;      // offset:0x00
    int Flags;      // offset:0x08
    int Reserved;   // offset:0x0c
    void *FuncPtr;  // offset:0x10
};

void (*block)() = 0;
((void (*)(__block_impl *))((__block_impl *)block)->FuncPtr)((__block_impl *)block);

Now block variable is 0 (nil), so block->FuncPtr points address 0x10 . Thus EXC_BAD_ACCESS (code=1, address=0x10) was occurred.

LLVM document says the same thing. http://clang.llvm.org/docs/Block-ABI-Apple.html#high-level

struct Block_literal_1 {
    void *isa; // initialized to &_NSConcreteStackBlock or &_NSConcreteGlobalBlock
    int flags;
    int reserved;
    void (*invoke)(void *, ...);

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