iAd AdBanner内存泄漏问题(应用程序崩溃)

我有一个简单的应用程序与列表/详细信息视图。 在详细视图中,我有1个webview,还显示1个iAd。 当我在列表/详细信息视图之间切换时,我的应用程序有时会崩溃。 我的iAd代码似乎有问题。 请你解决它。 我尝试使用泄漏,但我无法完全弄明白。

以下是更新的代码;

@interface DetailController : UIViewController  { 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. // eg 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实例。

  1. 为iAd添加实例变量
  2. 卸载视图时,请确保其委托设置为nil。
  3. 确保在卸载视图时释放它

在你的DetailController接口声明(.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);

 @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 //eg 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