本文介绍了iAd AdBanner内存泄漏问题(应用程序崩溃)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我有一个带有列表/详细信息视图的简单应用程序.在详细信息视图中,我有1个Web视图,并且还显示了1个iAd.当我在列表/详细视图之间切换时,我的应用有时会崩溃.我的iAd代码似乎有问题.请帮助我修复它.我尝试使用Leaks,但无法完全弄清.
I have a simple app with list/detail view. In the detail view, I have 1 webview and also show 1 iAd. As I toggle between list/detail view, my app crashes sometimes. It seems there is something wrong with my iAd code. Please hlp me fix it.I tried using Leaks, but am unable to figure it out completely.
下面是UPDATED代码;
Below is the UPDATED code;
@interface DetailController : UIViewController <UIWebViewDelegate,ADBannerViewDelegate> {
NSString *selectedTxt;
IBOutlet UIWebView* webView;
ADBannerView *adView_;
BOOL bannerIsVisible;
}
@property(nonatomic,retain) NSString *selectedTxt;
@property(nonatomic,retain) UIWebView* webView;
@property (nonatomic,retain) ADBannerView *adView;
@property (nonatomic,assign) BOOL bannerIsVisible;
@end
实施
@implementation DetailController
@synthesize selectedTxt;
@synthesize webView,bannerIsVisible;
@synthesize adView = adView_;
/*
// The designated initializer. Override if you create the controller programmatically and want to perform customization that is not appropriate for viewDidLoad.
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil {
if ((self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil])) {
// Custom initialization
}
return self;
}
*/
- (void) viewWillAppear:(BOOL)animated {
bannerIsVisible = YES;
adView_ = [[ADBannerView alloc] initWithFrame:CGRectZero];
float origin_y;
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
origin_y = 360.0;
else
origin_y = self.view.frame.size.height;
adView_.frame = CGRectMake(0.0,origin_y, adView_.frame.size.width, adView_.frame.size.height);
if ( &ADBannerContentSizeIdentifierPortrait != NULL ) {
adView_.requiredContentSizeIdentifiers = [NSSet setWithObject:ADBannerContentSizeIdentifierPortrait];
adView_.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
} else {
adView_.requiredContentSizeIdentifiers = [NSSet setWithObject:ADBannerContentSizeIdentifier320x50];
adView_.currentContentSizeIdentifier = ADBannerContentSizeIdentifier320x50;
}
adView_.delegate = self;
[webView addSubview:adView_];
[self.view bringSubviewToFront:adView_];
self.bannerIsVisible=NO;
[super viewWillAppear: animated];
}
// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
//Set the title of the navigation bar
//self.navigationItem.title = @"Selected Country";
[super viewDidLoad];
}
/*
// Override to allow orientations other than the default portrait orientation.
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation {
// Return YES for supported orientations
return YES;
}
*/
- (void)didReceiveMemoryWarning {
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
- (void)viewDidUnload {
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
adView_.delegate = nil;
self.adView = nil;
}
- (void)dealloc {
adView_.delegate = nil;
[adView_ release];
[super dealloc];
}
- (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
{
if (bannerIsVisible)
{
[UIView beginAnimations:@"animateAdBannerOff" context:NULL];
// assumes the banner view is at the bottom of the screen.
banner.frame = CGRectOffset(banner.frame, 0, 50); // if the banner is on top of the screen use -50
[UIView commitAnimations];
bannerIsVisible = NO;
}
}
- (void)bannerViewDidLoadAd:(ADBannerView *)banner
{
if (!bannerIsVisible)
{
[UIView beginAnimations:@"animateAdBannerOn" context:NULL];
// assumes the banner view is offset -50 pixels so that it is not visible.
banner.frame = CGRectOffset(banner.frame, 0, -50); // if the banner is on top of the screen use 50
[UIView commitAnimations];
bannerIsVisible = YES;
}
}
- (BOOL)bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave
{
NSLog(@"Banner view is beginning an ad action");
BOOL shouldExecuteAction = YES; // your application implements this method if you want it not fixed
if (!willLeave && shouldExecuteAction)
{
// insert code here to suspend any services that might conflict with the advertisement
}
return shouldExecuteAction;
}
@end
错误日志
2011-12-17 20:33:23.142 MyApp[4382:207] ADBannerView: WARNING A banner view (0x6236190) has an ad but may be obscured. This message is only printed once per banner view.
[Switching to process 4382 thread 0x920f]
2011-12-17 20:34:14.154 MyApp[4382:207] -[__NSCFType bannerViewDidLoadAd:]: unrecognized selector sent to instance 0x62542f0
2011-12-17 20:34:14.195 MyApp[4382:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFType bannerViewDidLoadAd:]: unrecognized selector sent to instance 0x62542f0'
*** Call stack at first throw:
(
0 CoreFoundation 0x00e025a9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x00f56313 objc_exception_throw + 44
2 CoreFoundation 0x00e040bb -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x00d73966 ___forwarding___ + 966
4 CoreFoundation 0x00d73522 _CF_forwarding_prep_0 + 50
5 CoreFoundation 0x00d72c7d __invoking___ + 29
6 CoreFoundation 0x00d72b51 -[NSInvocation invoke] + 145
7 CoreFoundation 0x00d73a04 ___forwarding___ + 1124
8 CoreFoundation 0x00d73522 _CF_forwarding_prep_0 + 50
9 iAd 0x000149f9 -[ADDistributedMessagingCenter messagePort:receivedMessage:withData:] + 251
10 iAd 0x00015012 ADMessagePortCallBack + 75
11 CoreFoundation 0x00db9f4c __CFMessagePortPerform + 396
12 CoreFoundation 0x00de3944 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
13 CoreFoundation 0x00d43cf7 __CFRunLoopDoSource1 + 215
14 CoreFoundation 0x00d40f83 __CFRunLoopRun + 979
15 CoreFoundation 0x00d40840 CFRunLoopRunSpecific + 208
16 CoreFoundation 0x00d40761 CFRunLoopRunInMode + 97
17 GraphicsServices 0x033ff1c4 GSEventRunModal + 217
18 GraphicsServices 0x033ff289 GSEventRun + 115
19 UIKit 0x00300c93 UIApplicationMain + 1160
20 MyApp 0x00002440 main + 102
21 MyApp 0x000023d1 start + 53
)
terminate called after throwing an instance of 'NSException'
[Switching to process 4382 thread 0x207]
推荐答案
您没有发布iAd实例.
You are not releasing your iAd instance.
- 为iAd添加实例变量
- 确保在卸载视图时将其委托设置为nil.
- 确保在卸载视图时将其释放
DetailController接口声明(.h)之内;
Within you DetailController interface declaration (.h);
@interface DetailController ...
{
...
//note, we are using an instance variable with the trailing underscore
ADBannerView *adView_;
}
//note, we are using an accessor without that trailing underscore - those are
//glued together using the synthesize mechanics within the implementation
@property (nonatomic,retain) ADBannerView *adView;
...
@end
DetailController实现(.m)之内;
Within you DetailController implementation (.m);
@implementation DetailController
//this will glue the instance variable with our property accessor
@sythesize adView = adView_;
...
-(void)viewDidLoad
{
[super viewDidLoad];
//retained by alloc/init, hence no need for using the retain by the accessor
adView_ = [[ADBannerView alloc] initWithFrame:CGRectZero];
//note, in case you want this adbanner to be initialized at a different point,
//like for example in viewWillAppear that you have to consider its former instance.
//to be on the safe side, you could prefix the above init with a [adView release];
...
}
-(void)viewDidUnload
{
[super viewDidUnload];
//as always, make sure the delegate is invalidated
adView_.delegate = nil;
//use accessor mechanics to release and invalidate for convenience
self.adView = nil;
}
-(void)dealloc
{
//to be on the safe side, make sure the adview is released even if
//viewDidUnload was not called
//e.g. nested viewControllers omitting viewDidUnload pass on
//as always, make sure the delegate is invalidated
adView_.delegate = nil;
//do NOT use accessor mechanics within init or dealloc for safety reasons
[adView_ release];
[super dealloc];
}
@end
这篇关于iAd AdBanner内存泄漏问题(应用程序崩溃)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!