2011-12-17 7 views
1

私はリスト/詳細ビューで簡単なアプリを持っています。詳細ビューでは、私は1つのwebviewを持っており、1つのiAdも表示します。私がリスト/詳細ビューを切り替えると、私のアプリケーションがクラッシュすることがあります。私のiAdコードに何か問題があるようです。私はそれを修正hlpしてください。 リークを使ってみましたが、完全に解明できませんでした。iAd AdBannerメモリリークの問題(アプリケーションがクラッシュする)

以下はUPDATEDコードです。

@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] 
+0

gdbコマンドライン内で 'po 0x62542f0'を実行します(その委任に対して呼び出されようとしたアドレスです)。 – Till

答えて

0

あなたの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 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 
+0

Thxたくさん..しかし、私はいくつかの質問があります。あなたがiAdのインスタンス変数を追加すると言うと、私はurがadViewを参照していると思います...また、間接的にプロパティを作成して合成するよう求めています。私のインターフェイスは.... @ interface DetailControllerとして宣言されています。UIViewController {...} deallocまたはviewDidUnloadのデリゲートにはどうしたらいいですか? – testndtv

+0

あなたが言っているポイントの大まかなコードスニペットは本当に素晴らしいでしょう...あなたがそれをやろうとすぐに質問を受け入れて閉じることができます。 – testndtv

+0

完了 - 強化された答えを見て、頼むことを躊躇しないでください詳細はこちら – Till

関連する問題