简体   繁体   中英

iAds: How can I prevent my AdBannerView delegate from getting called after the view has been released?

I'm adding iAds to my app and it's crashing because the AdBannerView delegate gets called after the view is released. I'm following the code examples in the Apple docs, as well as code samples I've found on the Apple Dev forums, but I'm missing something because it's crashing.

I create the AdBannerView in the viewDidLoad of the view I want display it in...

self.bannerIsVisible = NO;
self.adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0, 0, 1024, 66)];
adView.requiredContentSizeIdentifiers = [NSSet setWithObject:ADBannerContentSizeIdentifierLandscape];
adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierLandscape;
adView.delegate = self;
[self.view addSubview:adView];

I bring it to the front in the viewDidAppear...

[self.view bringSubviewToFront:[self adView]];
adView.frame = CGRectMake(0.0, 0.0, adView.frame.size.width, adView.frame.size.height);

I set it to nil in the viewDidUnload...

[[self adView] setDelegate:nil];
[self setAdView:nil];

and I release it in dealloc...

[adView release];

Yet, every now and then, the app crashes with this error...

-[MyViewController bannerView:didFailToReceiveAdWithError:]: message sent to deallocated instance 0xf61d820

What am I missing?

Thanks so much for your wisdom!

It's possible that viewDidUnload never gets called, if the view controller winds up being released before ever unloading the view. You will need to set the delegate to nil in dealloc too.


Also, I notice your memory handling of the ad view is wrong. I suspect that your adView property is declared retain and not assign . If so, then after this line

self.adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0, 0, 1024, 66)];

the "retain count" (not to be confused with the retainCount property, which should be ignored) of the ad banner is now two: one from the alloc and one from the assignment to the property. If it gets to viewDidUnload , then [self setAdView:nil] releases it once but then the reference is lost so the release in dealloc can never release it again to bring the "retain count" back to zero.

If, on the other hand, your adView actually is declared assign rather than retain , it's still wrong. In that case, [self setAdView:nil] in viewDidUnload drops the reference without ever releasing it, leaking the ad view.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM