You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS模拟器移植:SwiftUI MTKView Metal层传C++ metal-cpp崩溃排查

iOS平台模拟器移植:Metal渲染触发objc_release崩溃(内存管理问题)

我正在将一款游戏机模拟器移植到iOS平台,目标是让已经在macOS上测试通过的渲染器在iOS正常工作。模拟器核心采用C编写,通过metal-cpp实现渲染;iOS前端使用Swift结合SwiftUI开发,通过Objective-C桥接文件完成Swift与C++的交互。

在Swift侧创建MTKView,在其代理方法中运行模拟器一帧画面,并将视图的底层Metal层传给模拟器以渲染最终输出图像。模拟器运行返回后,Swift端在objc_release中崩溃,明确指向内存管理存在问题。

相关代码

桥接接口(ios_driver.h)

#pragma once
#include <Foundation/Foundation.h>
#include <QuartzCore/QuartzCore.h>

void iosCreateEmulator();
void iosRunFrame(CAMetalLayer* layer);

桥接实现(ios_driver.mm)

#import <Foundation/Foundation.h>

extern "C" {
#include "ios_driver.h"
}

<...>

#define IOS_EXPORT extern "C" __attribute__((visibility("default")))

std::unique_ptr<Emulator> emulator = nullptr;
IOS_EXPORT void iosCreateEmulator() { ... }

// Runs 1 video frame of the emulator and 
IOS_EXPORT void iosRunFrame(CAMetalLayer* layer) {
    void* layerBridged = (__bridge void*)layer;

    // Pass the CAMetalLayer to the emulator
    emulator->getRenderer()->setMTKLayer(layerBridged);
    // Runs the emulator for 1 frame and renders the output image using our layer
    emulator->runFrame();
}

MTKView代理(Swift)

class Renderer: NSObject, MTKViewDelegate {
    var parent: ContentView
    var device: MTLDevice!
    
    init(_ parent: ContentView) {
        self.parent = parent
        if let device = MTLCreateSystemDefaultDevice() {
            self.device = device
        }
        
        super.init()
    }
    
    func mtkView(_ view: MTKView, drawableSizeWillChange size: CGSize) {}
    
    func draw(in view: MTKView) {
        var metalLayer = view.layer as! CAMetalLayer
        // Run the emulator for 1 frame & display the output image
        iosRunFrame(metalLayer)
    }
}

模拟器渲染函数(C++/metal-cpp)

void RendererMTL::setMTKLayer(void* layer) {
    metalLayer = (CA::MetalLayer*)layer;
}

void RendererMTL::display() {
    CA::MetalDrawable* drawable = metalLayer->nextDrawable();
    if (!drawable) {
        return;
    }

    MTL::Texture* texture = drawable->texture();
   <rest of rendering follows here using the drawable & its texture>
}

已尝试的排查步骤

  • 原本认为使用CAMetalLayer*作为桥接参数时,Swift会自动处理ARC内存管理,但崩溃仍发生。
  • 尝试过多种传递方式(如直接传递MetalDrawable*)、仅打印Metal层信息、使用空实现的渲染器,只有空渲染器能正常运行,无崩溃现象。

需要解决该objc_release崩溃的内存管理问题,代码已上传至GitHub。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.14 01:14:54