QUI 메시징/경고 시스템으로 사용할 싱글 톤 클래스를 내 응용 프로그램에 제공하기 위해 GCD를 사용하고 있습니다. 싱글 톤은 NSMutable 배열에 메시지를 추가하는 addText라는 메서드를 포함하고 배열의 각 메시지를 사용자에게 표시합니다. 다음과 같이GCD를 통한 싱글 톤 문제
#import <UIKit/UIKit.h>
@interface Banner : UIView
+ (Banner*) sharedBanner;
- (id) initWithWindow:(UIWindow*)window;
- (void) addText:(NSString*)bannerText;
- (void) callNext;
@end
구현은 다음과 같습니다 :
헤더는 다음과 같습니다
문제가#import "Banner.h"
static Banner* sharedBanner=nil;
static dispatch_queue_t serialQueue;
@implementation Banner
{
@private
UILabel* bannerLabel;
NSMutableArray* textStrings;
BOOL triggered;
int counter;
NSTimer* timer;
UIButton* bannerButton;
CGRect defaultFrame;
}
+ (id)allocWithZone:(NSZone *)zone {
static dispatch_once_t onceQueue;
dispatch_once(&onceQueue, ^{
serialQueue = dispatch_queue_create("MyQueue.BannerQueue", NULL);
if(sharedBanner == nil)
{
sharedBanner = [super allocWithZone:zone];
}
});
return sharedBanner;
}
+ (Banner*) sharedBanner
{
static dispatch_once_t onceQueue;
dispatch_once(&onceQueue, ^{
sharedBanner = [[Banner alloc] init];
});
return sharedBanner;
}
- (id) initWithWindow:(UIWindow*)window
{
UIView* __block obj;
dispatch_sync(serialQueue,^
{
obj = [super initWithFrame:CGRectMake(0, 20, window.bounds.size.width, 0)];
if (obj)
{
[self setBackgroundColor:[UIColor clearColor]];
defaultFrame = self.frame;
timer = nil;
counter = 0;
triggered = NO;
bannerLabel = [[UILabel alloc] initWithFrame:obj.bounds];
textStrings = [[NSMutableArray alloc] init];
[bannerLabel setNumberOfLines:0];
[bannerLabel setLineBreakMode:UILineBreakModeWordWrap];
[bannerLabel setTextAlignment:UITextAlignmentCenter];
[bannerLabel setBackgroundColor:[UIColor blackColor]];
[bannerLabel setTextColor:[UIColor whiteColor]];
[bannerLabel setAlpha:0.55];
[self addSubview:bannerLabel];
bannerButton = [[UIButton alloc] initWithFrame:self.bounds];
[bannerButton addTarget:self action:@selector(complete) forControlEvents:UIControlEventTouchUpInside];
[bannerButton setBackgroundColor:[UIColor clearColor]];
[bannerButton setEnabled:NO];
[self addSubview:bannerButton];
[window addSubview:self];
[window bringSubviewToFront:self];
}
});
self=(Banner*)obj;
return self;
}
- (void) trigger
{
triggered = YES;
if ([textStrings count] > 0)
{
[bannerLabel setText:[textStrings objectAtIndex:0]];
[bannerLabel sizeToFit];
[self setFrame:CGRectMake(0, self.window.bounds.size.height - bannerLabel.frame.size.height, self.window.bounds.size.width, bannerLabel.frame.size.height)];
[bannerLabel setFrame:self.bounds];
[bannerButton setFrame:self.bounds];
[bannerButton setEnabled:YES];
[UIView animateWithDuration:1
animations:^
{
[bannerLabel setAlpha:1];
}
completion:^(BOOL finished)
{
if (finished)
{
timer = [NSTimer scheduledTimerWithTimeInterval:4
target:self
selector:@selector(fade)
userInfo:nil
repeats:NO];
}
}];
}
else
{
triggered = NO;
}
}
- (void) fade
{
[bannerButton setEnabled:NO];
if (timer)
{
timer = nil;
}
[UIView animateWithDuration:1
animations:^
{
[bannerLabel setAlpha:0];
}
completion:^(BOOL finished)
{
[self setFrame:defaultFrame];
[bannerLabel setFrame:defaultFrame];
[bannerButton setFrame:defaultFrame];
DebugLog(@"BANNER_textStrings: %@", [textStrings objectAtIndex:0]);
[textStrings removeObjectAtIndex:0];
[self trigger];
}];
}
- (void) addText:(NSString*)bannerText
{
dispatch_sync(serialQueue,^
{
[textStrings addObject:bannerText];
if (!triggered)
{
[self trigger];
}
});
}
- (void) callNext
{
counter++;
if (!triggered)
{
[self trigger];
}
}
@end
는 여러 메시지가 동시에 표시되고, 그들은, 응용 프로그램 충돌을 페이드 아웃 할 때 fade 메소드의 "removeItemAtIndex : 0"줄에.
누구든지 내가 잘못한 것을 밝힐 수 있습니까?
에픽 답. 그것을 사랑해! – jrturton
포인트가 찍혔습니다. 나는 튜토리얼을 따르고 있었지만, 그렇게하는 것은 잘못된 것이라고 생각한다. 사과. –
비록 내가 싱글 톤에 화를 냈지만 사과 할 필요는 없다. 계속 질문 해주세요 :) – hooleyhoop