I am dealing with an infuriating memory leak in regards to loading an interstitial ad via AdMob. When observing the memory in Xcode & Instruments, the memory jumps 10 MB every time I visit the view controller hosting the ad. Also when closing the app on my phone and reopening it, causes the memory to jump 30-40 mb as well which is just ridiculous.
I have tried profiling this in Instruments and the memory being allocated are all system libraries and nothing that points out to what is wrong. I have read other Stack Overflow answers such as ADMOB Memory Leaking? but no answer has helped me so far. Maybe somebody can tell me what is wrong with my code? I have followed the exact documentation AdMob provides which is https://developers.google.com/admob/ios/interstitial and all works fine except this crazy memory leak. Here is the exact code that is causing the leak below.
class ViewController: UIViewController, GADInterstitialDelegate {
var interstitial: GADInterstitial!
override func viewDidLoad() {
interstitial = createAndLoadInterstitial()
interstitial.delegate = self
}
func update() {
if interstitial.isReady {
interstitial.present(fromRootViewController: self)
}
}
func createAndLoadInterstitial() -> GADInterstitial {
let interstitial = GADInterstitial(adUnitID: "ca-app-pub-3940256099942544/4411468910")
interstitial.delegate = self
let request = GADRequest()
interstitial.load(request)
return interstitial
}
func interstitialDidDismissScreen(_ ad: GADInterstitial) {
interstitial = createAndLoadInterstitial()
}
// I am calling update() inside a button when pressed in this VC.
I just want to say that this actually has been solved by me. I did as one of the above stated in the comments. I took my code that was on the view controller hosting the interstitial ad and moved it to the app delegate. I simply then just referenced the interstitial ad object whenever I need it in my project. This brought the memory back down to whatever it allocated upon visiting the controller hosting the ad. For those that want to see a very simple example of what this looks like in the app delegate:
import UIKit
import GoogleMobileAds
@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate, GADInterstitialDelegate {
var myInterstitial: GADInterstitial!
func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?) -> Bool {
GADMobileAds.sharedInstance().start(completionHandler: nil)
myInterstitial = createAndLoadInterstitial()
return true
}
func createAndLoadInterstitial() -> GADInterstitial {
let interstitial = GADInterstitial(adUnitID: "yourAdID")
interstitial.delegate = self
let request = GADRequest()
interstitial.load(request)
return interstitial
}
func interstitialDidDismissScreen(_ ad: GADInterstitial) {
myInterstitial = createAndLoadInterstitial()
}