Objective c 奇怪的内核地址异常无效?

Objective c 奇怪的内核地址异常无效?,objective-c,exc-bad-access,Objective C,Exc Bad Access,我面临一个奇怪的OC异常,看起来我正在向一个发布的地址发送消息,但是当我 尝试检查它是否为空,它仍然会崩溃 尝试调试或添加@try@catch,它只捕获运行数天的内容,根本没有崩溃 例外情况 Exception Type: EXC_BAD_ACCESS (SIGSEGV) Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000010 VM Region Info: 0x10 is not in any region. Bytes

我面临一个奇怪的OC异常,看起来我正在向一个发布的地址发送消息,但是当我

  • 尝试检查它是否为空,它仍然会崩溃
  • 尝试调试或添加@try@catch,它只捕获运行数天的内容,根本没有崩溃
  • 例外情况

    Exception Type:  EXC_BAD_ACCESS (SIGSEGV)
    Exception Subtype: KERN_INVALID_ADDRESS at 0x0000000000000010
    VM Region Info: 0x10 is not in any region.  Bytes before following region: 4304617456
          REGION TYPE                      START - END             [ VSIZE] PRT/MAX SHRMOD  REGION DETAIL
          UNUSED SPACE AT START
    --->  
          __TEXT                        100934000-100a98000        [ 1424K] r-x/r-x SM=COW  ...x/APP
    
    Termination Signal: Segmentation fault: 11
    Termination Reason: Namespace SIGNAL, Code 0xb
    Terminating Process: exc handler [18302]
    Triggered by Thread:  22
    
    下面的代码并不严格,只显示逻辑(代码在一个串行调度队列中运行)


    有人能帮我下一步如何修复此错误吗?

    如果我理解正确,您希望将对Objective-C对象的引用存储为
    void*
    。例如,这与作为回调传递到工作表的旧式
    上下文
    用户信息
    指针类似

    有关示例,请参见。我还假设您使用的是ARC(请阅读)

    假设struct的生命周期比Objective-C对象的生命周期长,并且在struct中显式地设置和释放对象,那么内存管理就不需要字典了

    一旦分配了结构和对象(分别使用
    malloc
    [[XX alloc]init]
    ),您就可以使用
    (\u bridge\u retained void*)
    cast将对象的所有权转移到ARC之外,并将其存储在
    st->arg中

    要使用该对象,请使用
    (\uu-bridge-NSObject*)
    强制转换。这不会改变所有权

    准备释放对象时,使用
    (\uu bridge\u transfer NSObject*)
    通过强制转换将所有权传递回ARC。然后可以将
    void*
    指针设置为
    NULL

    所以总的来说:

    struct st_type {
        void *arg; 
    };
    
    void init()
    {
        NSObject *obj = [[NSObject alloc] init];
        struct st_type *st = malloc(sizeof(struct st_type));
        // transfer ownership out of ARC
        st->arg = (__bridge_retained void *)obj;
    }
    
    void use_struct(struct st_type *st){
        // no change in ownership
        NSObject *obj = (__bridge NSObject *)st->arg;
        // use `obj`
    }
    
    void release_object(struct st_type *st){
        // transfer ownership back to ARC
        NSObject *obj = (__bridge_transfer NSObject *)st->arg;
        st->arg = NULL;
    }
    

    这是ObjC中的一种非典型模式。你想完成什么?
    st_type
    的目的是在
    dictionary
    处理内存管理时传递非类型化对象吗?可能还有另一种方法可以做到这一点。它是示例,在项目中不是真实的。这样编写的代码是因为它是oc和c库之间的桥梁。st_类型是由c lib管理的结构体。
    obj
    的生存期是否与结构体的生存期相关联?
    dictionary
    的目的是什么?dictionary是oc对象的存储,以防止其释放,struct的生存期比oc对象长,但当oc需要解除锁定时,它会将struct的指针设置为NULL。虽然这不是异常的主要原因,但我认为这是使用
    的最佳实践。非常感谢。
    struct st_type {
        void *arg; 
    };
    
    void init()
    {
        NSObject *obj = [[NSObject alloc] init];
        struct st_type *st = malloc(sizeof(struct st_type));
        // transfer ownership out of ARC
        st->arg = (__bridge_retained void *)obj;
    }
    
    void use_struct(struct st_type *st){
        // no change in ownership
        NSObject *obj = (__bridge NSObject *)st->arg;
        // use `obj`
    }
    
    void release_object(struct st_type *st){
        // transfer ownership back to ARC
        NSObject *obj = (__bridge_transfer NSObject *)st->arg;
        st->arg = NULL;
    }