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

Swift 6中使用MPMediaItemArtwork遇主线程数据竞争警告求助

解决MPMediaItemArtwork requestHandler主线程执行问题

问题根源

MPMediaItemArtwork的requestHandler回调会被系统在后台线程触发,Swift 6的并发安全检查会检测到NSImage(AppKit UI组件)在非主线程被访问,从而抛出数据竞争警告。你之前尝试的async/await扩展只是在主线程创建MPMediaItemArtwork实例,但无法改变requestHandler的执行线程,因此警告依然存在。

解决方案:强制在主线程执行requestHandler逻辑

因为requestHandler是同步回调(必须立即返回图片),可以用DispatchQueue.main.sync将图片返回逻辑强制切换到主线程执行,确保NSImage的操作在主线程完成:

import SwiftUI
import MediaPlayer

struct ContentView: View {
    var body: some View {
        Text("Test")
            .padding()
            .task {
                await MainActor.run {
                    let nowPlayingInfoCenter = MPNowPlayingInfoCenter.default()
                    var nowPlayingInfo = [String: Any]()
                    guard let image = NSImage(named: "image") else { return }
                    
                    nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: image.size) { _ in
                        // 强制在主线程执行图片返回逻辑
                        return DispatchQueue.main.sync {
                            image
                        }
                    }
                    
                    nowPlayingInfoCenter.nowPlayingInfo = nowPlayingInfo
                }
            }
    }
}

补充说明

  1. 为什么用sync而不是async?
    requestHandler要求同步返回结果,async会导致回调提前返回空值,不符合API要求;sync会阻塞当前后台线程,直到主线程完成图片返回操作,确保数据一致性。

  2. 额外优化:提前预处理图片
    如果图片需要裁剪、缩放等操作,可以提前在主线程完成处理,保存为CGImage或预渲染的NSImage,再在requestHandler中直接返回,减少主线程阻塞:

// 主线程提前处理图片(示例:缩放图片)
let targetSize = NSSize(width: 300, height: 300)
let processedImage = NSImage(size: targetSize) { rect in
    image.draw(in: rect)
}

nowPlayingInfo[MPMediaItemPropertyArtwork] = MPMediaItemArtwork(boundsSize: processedImage.size) { _ in
    DispatchQueue.main.sync {
        processedImage
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 07:33:29