我编写了Singleton类来管理iAd。用户闲置5秒钟后,iAd会弹出。 idleTimerExceeded 调用会生成一个通知,以显示iAd。这段代码可以很好地满足我的要求,但是由于我不熟悉iOS开发,因此在集成了此代码后,我的应用程序有时会意外挂起。该代码会导致许多警告等。我想在内存和性能方面优化我的代码。
非常感谢您的建议和评论。
下面是我的代码:
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
最佳答案
这就是你所需要的。该代码是线程安全的,并且不会有任何内存问题和警告。
+ (iAdSingleton *) sharedInstance
{
static dispatch_once_t onceToken;
static iAdSingleton * __sharedInstance = nil;
dispatch_once(&onceToken, ^{
__sharedInstance = [[self alloc] init];
});
return __sharedInstance;
}