You need to enable JavaScript to run this app. 在Block内使用__block修饰的C++类变量触发_Block_copy崩溃如何解决
优惠活动
大模型
产品
解决方案
定价
更多

在Block内使用__block修饰的C++类变量触发_Block_copy崩溃如何解决

问题根因

  • 语法疏漏:__block MyClass obj(a1 c1); 两个构造参数间遗漏了逗号,应为__block MyClass obj(a1, c1);,该问题会导致编译失败,不是运行时崩溃的直接原因。
  • 核心崩溃原因:
    1. 你显式删除了MyClass的左值拷贝构造函数,仅保留了移动构造函数。当你用__block修饰栈上的MyClass对象时,dispatch_async的内层Block会被拷贝到堆区,系统在拷贝__block修饰的C++对象时会默认尝试调用拷贝构造函数,拷贝构造被删除后对象无法正确拷贝,触发_Block_copy内部的内存操作崩溃。
    2. __block语义本身是用于支持在Block内部修改外部栈变量,你当前场景仅需要将对象传递到异步Block中使用,使用__block属于不必要的错误用法,额外引入了对象拷贝的风险。

修复方案

方案1:堆上分配对象,用智能指针管理(兼容性最好)

将MyClass放到堆上,用智能指针持有,避免C++对象直接被Block拷贝:

#include <memory>

my_processor = ^(int* c1, const int* a1){
  std::shared_ptr<MyClass> obj = std::make_shared<MyClass>(a1, c1);
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {                
     ProcessMyData(*obj);
  });
};

如果不需要多持有者,也可以用std::unique_ptr配合移动语义传入Block。

方案2:移除__block修饰,用移动语义转移对象所有权

不需要__block修饰,直接将对象移动到异步Block中,触发你已经实现的移动构造函数,避免拷贝:

my_processor = ^(int* c1, const int* a1){
  MyClass obj(a1, c1);
  dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {                
     ProcessMyData(std::move(obj));
  });
};

该方案要求你当前编译环境开启了C++11及以上的语言标准。

内容的提问来源于stack exchange,提问作者Harry

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.14 04:06:00