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

iOS集成AdMob遇Thread 1错误:隐式解包Optional值为nil

解决AdMob初始化时的"Unexpectedly found nil"崩溃问题

你遇到的这个崩溃完全是因为代码执行顺序错误导致的:你在还没初始化bannerView的情况下,就尝试给它的adUnitID等属性赋值,而bannerView被声明为隐式解包的Optional(var bannerView: GADBannerView!),此时访问它自然会触发nil崩溃。

问题代码的关键错误点

  • 你先执行了bannerView.adUnitID = "ca-app-pub-xxxxx/xxxxx",但此时bannerView还没有被实例化,值为nil
  • 初始化bannerView的代码bannerView = GADBannerView(adSize: kGADAdSizeBanner)被放在了属性赋值之后
  • 辅助函数addBannerViewToView被定义在了viewDidLoad内部,虽然能运行,但不符合Swift代码规范

修正后的完整代码

import UIKit
import GoogleMobileAds

class ViewController: UIViewController, GADBannerViewDelegate {
    var bannerView: GADBannerView!
    
    override func viewDidLoad() {
        super.viewDidLoad()
        
        // 第一步:先初始化bannerView实例
        bannerView = GADBannerView(adSize: kGADAdSizeBanner)
        bannerView.delegate = self
        
        // 第二步:再设置广告单元ID和根视图控制器
        bannerView.adUnitID = "ca-app-pub-xxxxx/xxxxx"
        bannerView.rootViewController = self
        
        // 第三步:添加到视图并设置约束
        addBannerViewToView(bannerView)
        
        // 最后:发起广告请求
        bannerView.load(GADRequest())
    }
    
    // 把辅助函数移到viewDidLoad外部,符合代码规范
    func addBannerViewToView(_ bannerView: GADBannerView) {
        bannerView.translatesAutoresizingMaskIntoConstraints = false
        view.addSubview(bannerView)
        view.addConstraints(
            [NSLayoutConstraint(item: bannerView, attribute: .bottom, relatedBy: .equal, toItem: view.safeAreaLayoutGuide, attribute: .bottom, multiplier: 1, constant: 0),
             NSLayoutConstraint(item: bannerView, attribute: .centerX, relatedBy: .equal, toItem: view, attribute: .centerX, multiplier: 1, constant: 0)
            ])
    }
    
    /// Tells the delegate an ad request loaded an ad.
    func adViewDidReceiveAd(_ bannerView: GADBannerView) {
        print("adViewDidReceiveAd")
    }
    
    /// Tells the delegate an ad request failed.
    func adView(_ bannerView: GADBannerView, didFailToReceiveAdWithError error: GADRequestError) {
        print("adView:didFailToReceiveAdWithError: \(error.localizedDescription)")
    }
    
    /// Tells the delegate that a full-screen view will be presented in response
    /// to the user clicking on an ad.
    func adViewWillPresentScreen(_ bannerView: GADBannerView) {
        print("adViewWillPresentScreen")
    }
    
    /// Tells the delegate that the full-screen view will be dismissed.
    func adViewWillDismissScreen(_ bannerView: GADBannerView) {
        print("adViewWillDismissScreen")
    }
    
    /// Tells the delegate that the full-screen view has been dismissed.
    func adViewDidDismissScreen(_ bannerView: GADBannerView) {
        print("adViewDidDismissScreen")
    }
    
    /// Tells the delegate that a user click will open another app (such as
    /// the App Store), backgrounding the current app.
    func adViewWillLeaveApplication(_ bannerView: GADBannerView) {
        print("adViewWillLeaveApplication")
    }
    
    let adSize = GADAdSizeFromCGSize(CGSize(width: 300, height: 50))
}

额外的优化提示

  • 我把约束里的bottomLayoutGuide换成了view.safeAreaLayoutGuide,这是iOS 11+更安全的布局方式,避免广告被底部刘海遮挡
  • 确保你已经在Info.plist里正确配置了AdMob的应用ID(GADApplicationIdentifier),这也是容易忽略的坑点

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 00:42:44