【问题标题】:iAds: How can I prevent my AdBannerView delegate from getting called after the view has been released?iAds:如何防止我的 AdBannerView 委托在视图发布后被调用?
【发布时间】:2011-04-11 02:25:15
【问题描述】:

我正在向我的应用添加 iAd,但它崩溃了,因为在视图发布后调用了 AdBannerView 委托。我正在关注 Apple 文档中的代码示例,以及我在 Apple Dev 论坛上找到的代码示例,但我遗漏了一些东西,因为它崩溃了。

我在要在其中显示的视图的 viewDidLoad 中创建 AdBannerView...

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];

我把它放在 viewDidAppear 的前面...

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

我在 viewDidUnload 中将它设置为 nil...

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

然后我在 dealloc 中释放它...

[adView release];

然而,应用程序时不时会因此错误而崩溃...

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

我错过了什么?

非常感谢您的智慧!

【问题讨论】:

    标签: iphone ios ipad iad


    【解决方案1】:

    如果视图控制器在卸载视图之前被释放,viewDidUnload 可能永远不会被调用。您还需要在 dealloc 中将委托设置为 nil。


    另外,我注意到您对广告视图的记忆处理是错误的。我怀疑您的adView 属性声明为retain 而不是assign。如果是,那么在这一行之后

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

    广告横幅的“保留计数”(不要与应忽略的 retainCount 属性混淆)现在是两个:一个来自分配,另一个来自分配给属性。如果它到达viewDidUnload,则[self setAdView:nil] 释放它一次,但随后引用丢失,因此dealloc 中的释放永远不能再次释放它以使“保留计数”回到零。

    另一方面,如果您的 adView 实际上被声明为 assign 而不是 retain,那么它仍然是错误的。在这种情况下,viewDidUnload 中的 [self setAdView:nil] 会丢弃引用而不释放它,从而泄露广告视图。

    【讨论】:

    • 感谢 Anomie,感谢您了解这一点。我刚刚修复了它,到目前为止还没有发生崩溃,但是一开始它是间歇性的,所以如果它仍然发生,我会告诉你。再次感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-08-04
    • 1970-01-01
    • 2011-03-21
    • 1970-01-01
    相关资源
    最近更新 更多