title: Singleton class for displaying iAds for iPhone
body: <p>I have written a Singleton Class for managing iAds.The iAds pop up after 5 seconds of the user inactivity. The <strong>idleTimerExceeded</strong> call generate a notification to show the iAd. This code works fine for my requirements but since I am new to iOS development, my application sometimes hangs unexpectedly after integrating this code. This code results in lots of warnings etc. I would like to optimize my code in terms of memory and performance.</p>
  
  <p>I would be very thankful for your kind suggestions and reviews.</p>
  
  <p>Below is my code:</p>
  
  <p><strong>iAdSingleton.h</strong></p>
  
  <pre><code>#import &lt;Foundation/Foundation.h&gt;
  #import "AppDelegate.h"
  #import "iAd/iAd.h"
  
  @interface iAdSingleton : UIViewController&lt;ADBannerViewDelegate&gt; {
      ADBannerView *adView;
      UIViewController *displayVC;
      NSTimer *idleTimer;
      BOOL isItFirstTime;
  }
  @property (nonatomic, retain) ADBannerView *adView;
  @property (nonatomic, retain) UIViewController *displayVC;
  @property (nonatomic) BOOL isItFirstTime;
  
  + (id) shareAdSingleton;
  - (void) resetIdleTimer;
  - (void) idleTimerExceeded;
  
  @end
  </code></pre>
  
  <p><strong>iAdSingleton.m</strong></p>
  
  <pre><code>#import "iAdSingleton.h"
  
  @implementation iAdSingleton
  
  static iAdSingleton* _sharedAdSingleton = nil;
  
  BOOL bannerVisible = NO;
  BOOL controlAccessBannerVisibility = NO;
  @synthesize adView, displayVC;
  @synthesize isItFirstTime;
  
  #define kMaxIdleTimeSeconds 5.0
  
  +(id)sharedAdSingleton
  {
      @synchronized(self)
      {
          if(!_sharedAdSingleton)
              _sharedAdSingleton = [[self alloc] init];
          return _sharedAdSingleton;
      }
      return nil;
  }
  
  +(id)alloc
  {
      @synchronized([iAdSingleton class])
      {
          NSAssert(_sharedAdSingleton == nil, @"Attempted to allocate a second instance of a singleton.");
          _sharedAdSingleton = [super alloc];
          return _sharedAdSingleton;
      }
  
      return nil;
  }
  
  -(id)init
  {
      self = [super init];
      if (self != nil) {
  
      /*                  Initialize The Parameters Over Here                  */
  
          //adView = [[ADBannerView alloc] initWithFrame:CGRectMake(0, 480, 0, 0)];
          adView = [[ADBannerView alloc] init];
          adView.currentContentSizeIdentifier = ADBannerContentSizeIdentifierPortrait;
          self.adView.delegate=self;
          [self resetIdleTimer];
      }
      return self;
  }
  
  -(void)dealloc
  {
      displayVC = nil;
      if (adView) {
          [adView removeFromSuperview]; //Remove ad view from superview
          [adView setDelegate:nil];
          adView = nil;
      }
      [super dealloc];
  }
  
  -(UIViewController *)viewControllerForPresentingModalView
  {
      return displayVC;
  }
  
  - (void)bannerViewDidLoadAd:(ADBannerView *)banner 
  {
      banner.hidden = NO;
      if(!bannerVisible){
          NSLog(@"Banner Changes 1 - Purpose: Visibility");
          // [UIView beginAnimations:@"bannerAppear" context:NULL];
          // banner.frame = CGRectOffset(banner.frame, 0, -100);
          // [UIView commitAnimations];
          bannerVisible = YES;
          controlAccessBannerVisibility = YES;
  
      }
  }
  
  - (void)bannerView:(ADBannerView *)banner didFailToReceiveAdWithError:(NSError *)error
  {
      //NSLog(@"Unable to receive Ad.");
      NSLog(@"Banner Changes 2 - Purpose: Unable to Receive Ad.");
      banner.hidden = YES;
      if(bannerVisible){
          [UIView beginAnimations:@"bannerDisappear" context:NULL];
          banner.frame = CGRectOffset(banner.frame, 0, 100);
          [UIView commitAnimations];
          bannerVisible = NO;
      }
  }
  
  - (BOOL) bannerViewActionShouldBegin:(ADBannerView *)banner willLeaveApplication:(BOOL)willLeave
  {
      NSLog(@"Pause anything necessary");
      return YES;
  }
  
  - (void) bannerViewActionDidFinish:(ADBannerView *)banner
  {
      NSLog(@"We now resume to normal operations");
  }
  
  - (void)resetIdleTimer {
  
      if (!idleTimer) {
          idleTimer = [[NSTimer scheduledTimerWithTimeInterval:kMaxIdleTimeSeconds
                                                        target:self
                                                      selector:@selector(idleTimerExceeded)
                                                      userInfo:nil
                                                       repeats:NO] retain];
      }
      else {
          if (fabs([idleTimer.fireDate timeIntervalSinceNow]) &lt; kMaxIdleTimeSeconds-1.0) {
              [idleTimer setFireDate:[NSDate dateWithTimeIntervalSinceNow:kMaxIdleTimeSeconds]];
              /*
               Notification: HideAd
               */
  
              NSLog(@"Notification Generated For HideAd");
              [[NSNotificationCenter defaultCenter] postNotificationName:@"HideAdBanner" object:nil userInfo:nil];
  
          }
      }
  }
  
  - (void)idleTimerExceeded {
  
      AppDelegate *appDel = (AppDelegate *)[[UIApplication sharedApplication] delegate];
  
      if (appDel.adVisible == NO) {
          NSLog(@"Notification Generated For ShowAd");
  
          /*
           Notification: ShowAd
           */
  
          if (controlAccessBannerVisibility == YES) {
              [[NSNotificationCenter defaultCenter] postNotificationName:@"ShowAdBanner" object:nil userInfo:nil];
          }
      }
  }
  
  @end
  </code></pre>