Singleton class for displaying iAds for iPhone

iad, ios4, ios5, xcode4

Solution

This is what you need. This code is thread safe as well as will not have any memory issue and warnings.

+ (iAdSingleton *) sharedInstance
{
    static dispatch_once_t onceToken;
    static iAdSingleton * __sharedInstance = nil;

    dispatch_once(&onceToken, ^{
        __sharedInstance = [[self alloc] init];
    });

    return __sharedInstance;
}

Problem

I have written a Singleton Class for managing iAds.The iAds pop up after 5 seconds of the user inactivity. The idleTimerExceeded 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. I would be very thankful for your kind suggestions and reviews. Below is my code: iAdSingleton.h ``` #import <Foundation/Foundation.h> #import "AppDelegate.h" #import "iAd/iAd.h" @interface iAdSingleton : UIViewController<ADBannerViewDelegate> { 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 ``` iAdSingleton.m ``` #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]) < 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 ```

Original source