我有一个模态视图,其中当用户执行某些操作时开始倒计时。在倒计时结束时,模态视图将关闭。以下是我为实现该目标而编写的过程,但不幸的是,它导致了一些线程问题。有没有办法以没有潜在线程问题的方式重写它?
- (void)countDown {
static int i = 3;
if (i == 3) {
i--;
UIImage *three = [UIImage imageNamed:@"Three"];
countDownFlag = [[UIImageView alloc] initWithImage:three];
countDownFlag.frame = CGRectMake(0, 370, countDownFlag.frame.size.width, countDownFlag.frame.size.height);
countDownFlag.center = CGPointMake(width / 2, countDownFlag.center.y);
[self.view addSubview:countDownFlag];
[self performSelector:@selector(countDown) withObject:nil afterDelay:0.5];
} else if (i == 2) {
i--;
UIImage *two = [UIImage imageNamed:@"Two"];
[countDownFlag setImage:two];
[self performSelector:@selector(countDown) withObject:nil afterDelay:0.5];
} else if (i == 1) {
i--;
UIImage *one = [UIImage imageNamed:@"One"];
[countDownFlag setImage:one];
[self performSelector:@selector(countDown) withObject:nil afterDelay:0.5];
} else {
[self dismissViewControllerAnimated:YES completion:nil];
}
}
编辑:图片显示了 XCode 告诉我的问题
更多编辑:
我的代码已更改以反射(reflect) vadian 的答案。这是更新
- (void)startCountDown {
NSLog(@"starting count down");
counter = 3;
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(countDown:) userInfo:nil repeats:YES];
}
- (void)countDown:(NSTimer *)timer {
if (counter == 3) {
countDownFlag = [[UIImageView alloc] init];
countDownFlag.frame = CGRectMake(0, 370, countDownFlag.frame.size.width, countDownFlag.frame.size.height);
countDownFlag.center = CGPointMake(width / 2, countDownFlag.center.y);
dispatch_async(dispatch_get_main_queue(), ^{
[self.view addSubview:countDownFlag];
});
} else if (counter == 0) {
[timer invalidate];
[self dismissViewControllerAnimated:YES completion:nil];
return;
}
NSArray *imageNameArray = @[@"", @"One", @"Two", @"Three"];
UIImage *image = [UIImage imageNamed:imageNameArray[counter]];
dispatch_async(dispatch_get_main_queue(), ^{
[self.countDownFlag setImage:image];
});
counter--;
}
我新猜测问题可能出在调用倒计时的代码上。这是执行此操作的代码。
- (void)changeLanguage:(BOOL) isMyanmar {
if (hasRun == YES) {
return;
}
hasRun = YES;
NSUserDefaults * userdefaults = [NSUserDefaults standardUserDefaults];
[userdefaults setBool:isMyanmar forKey:@"myanmar"];
[userdefaults synchronize];
[self updateCurrentLanguageText];
if ([self isMyanmar]) {
[self changeLanguageFlag:@"MyanmarFlagBig"];
} else {
[self changeLanguageFlag:@"UnitedKingdomFlagBig"];
}
//>>>>>>>>>>>>>>>>>>>> the problem is probably here
[self startCountDown];
}
更改语言代码后运行的任何代码都会失败。问题可能就在那里。
编辑:线程问题消失了,但倒计时不再发生。
在我将代码移入
changeLanguage
之后进入调用它的方法,问题就神秘地消失了。 (重复但有效。)- (void)changeLanguageToEnglish {
[theLock lock];
if (hasRun == YES) {
[theLock unlock];
return;
}
hasRun = YES;
[userdefaults setBool:false forKey:@"myanmar"];
[userdefaults synchronize];
[self updateCurrentLanguageText];
if ([self isMyanmar]) {
[self changeLanguageFlag:@"MyanmarFlagBig"];
} else {
[self changeLanguageFlag:@"UnitedKingdomFlagBig"];
}
[self startCountDown];
[theLock unlock];
}
- (void)changeLanguageToMyanmar {
[theLock lock];
if (hasRun == YES) {
[theLock unlock];
return;
}
hasRun = YES;
[userdefaults setBool:true forKey:@"myanmar"];
[userdefaults synchronize];
[self updateCurrentLanguageText];
if ([self isMyanmar]) {
[self changeLanguageFlag:@"MyanmarFlagBig"];
} else {
[self changeLanguageFlag:@"UnitedKingdomFlagBig"];
}
[self startCountDown];
[theLock unlock];
}
但问题是倒计时不再发生。
最佳答案
您可以使用 NSTimer 来执行倒计时和计数器的静态变量。
方法startCountDown
启动计时器。
方法countDown:(NSTimer *)timer
每 0.5 秒调用一次。传递的 NSTimer 参数正是已经启动的计时器。
它根据其值执行操作并递减计数器。如果计数器为 0,则计时器无效并且 Controller 关闭。
static UInt8 counter = 0;
- (void)startCountDown {
countDownFlag = [[UIImageView alloc] init];
countDownFlag.frame = CGRectMake(0, 370, countDownFlag.frame.size.width, countDownFlag.frame.size.height);
countDownFlag.center = CGPointMake(width / 2, countDownFlag.center.y);
[self.view addSubview:countDownFlag];
counter = 3;
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(countDown:) userInfo:nil repeats:YES];
}
- (void)countDown:(NSTimer *)timer {
if (counter == 0) {
[timer invalidate];
[self dismissViewControllerAnimated:YES completion:nil];
return;
}
NSArray *imageNameArray = @[@"", @"One", @"Two", @"Three"];
UIImage *image = [UIImage imageNamed:imageNameArray[counter]];
dispatch_async(dispatch_get_main_queue(), ^{
[self.countDownFlag setImage:image];
});
counter--;
}
关于ios - 倒计时和关闭模态视图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31339401/