简体   繁体   English

使用EXC_BAD_ACCESS的Objective-C回调函数错误

[英]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) 我的应用程序在这里崩溃并出现错误: 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. 您可以调用第二个getRemoteImageWithObjectId方法,而不是第一个getRemoteImageWithObjectId方法。 So getImageCallback variable was nil at that time. 因此,那时的getImageCallback变量为nil。 The reason of EXC_BAD_ACCESS (code=1, address=0x10) might be calling the nil getImageCallback block. EXC_BAD_ACCESS (code=1, address=0x10)可能是调用nil getImageCallback块。

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. 例如,如果在64位环境上编译并执行以下Objective-C代码,则将获得地址= 0x10的完全相同的EXC_BAD_ACCESS。

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

You can double check this code in C++ with clang -rewrite-objc option. 您可以使用clang -rewrite-objc选项在C ++中-rewrite-objc检查此代码。 This Objective-C code was compiled as the following C++ code. 该Objective-C代码被编译为以下C ++代码。

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 . 现在block变量为0(nil),因此block->FuncPtr指向地址0x10 Thus EXC_BAD_ACCESS (code=1, address=0x10) was occurred. 因此发生了EXC_BAD_ACCESS (code=1, address=0x10)

LLVM document says the same thing. LLVM文件说了同样的话。 http://clang.llvm.org/docs/Block-ABI-Apple.html#high-level 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 *, ...);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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