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

主线程调用方法触发UI无响应警告,Admob启动代码位置是否合理?

问题
  • 主线程收到错误提示:"This method should not be called on the main thread as it may lead to UI unresponsiveness."
  • 多数场景UI响应正常,但偶尔出现无响应,尤其是使用Link()跳转APP外部链接时,怀疑是新增的Google AdMob代码导致。
  • 相关代码:
import SwiftUI
import BackgroundTasks
import GoogleMobileAds
import UserNotifications


@main
struct Test_ProjectApp: App {
    
    init(){
        GADMobileAds.sharedInstance().start(completionHandler: nil)
                
        let isNotificationsEnabled = UserDefaults.standard.bool(forKey: "isNotificationsEnabled")
        if isNotificationsEnabled {
            UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
                if granted {
                    print("Notifications permission granted.")
                    exampleNotification()
                } else {
                    print("Notifications permission denied because: \(error?.localizedDescription ?? "unknown error").")
                }
            }
        }
    }
    
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onOpenURL(perform: { url in
                    
                })
        }
    }
}
回答

当前调用GADMobileAds.sharedInstance().start()的位置不合适,必须调整。

原因

App的init()方法运行在主线程,而GADMobileAds.start()属于可能耗时的初始化操作,会阻塞主线程,这正是错误提示的来源,也是你偶尔遇到UI无响应的核心诱因。

调整方案

将AdMob的初始化逻辑移到后台线程执行,避免占用主线程资源:

import SwiftUI
import BackgroundTasks
import GoogleMobileAds
import UserNotifications

@main
struct Test_ProjectApp: App {
    
    init(){
        // 后台线程初始化AdMob,避免阻塞主线程
        DispatchQueue.global(qos: .background).async {
            GADMobileAds.sharedInstance().start(completionHandler: nil)
        }
                
        let isNotificationsEnabled = UserDefaults.standard.bool(forKey: "isNotificationsEnabled")
        if isNotificationsEnabled {
            UNUserNotificationCenter.current().requestAuthorization(options: [.alert, .sound, .badge]) { granted, error in
                if granted {
                    print("Notifications permission granted.")
                    // 若exampleNotification()涉及UI操作,必须切回主线程执行
                    DispatchQueue.main.async {
                        exampleNotification()
                    }
                } else {
                    print("Notifications permission denied because: \(error?.localizedDescription ?? "unknown error").")
                }
            }
        }
    }
    
    var body: some Scene {
        WindowGroup {
            ContentView()
                .onOpenURL(perform: { url in
                    
                })
        }
    }
}

额外注意

  • 如果exampleNotification()包含UI相关操作(比如更新界面状态、弹出提示),必须放在DispatchQueue.main.async中执行,因为通知权限的回调默认在后台线程运行。
  • 后续新增的AdMob相关初始化操作,都优先放在后台线程完成,仅将UI交互逻辑切回主线程。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 10:32:04