ios - 倒计时和关闭模态视图

标签 ios objective-c

我有一个模态视图,其中当用户执行某些操作时开始倒计时。在倒计时结束时,模态视图将关闭。以下是我为实现该目标而编写的过程,但不幸的是,它导致了一些线程问题。有没有办法以没有潜在线程问题的方式重写它?

- (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 告诉我的问题

output

更多编辑:

我的代码已更改以反射(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/

相关文章:

javascript - 如何将应用程序从浏览器重定向到 Safari?

html - 即使声明了文档类型,iOS Chrome 表格也不会显示 block

ios - 如何在每个 View Controller 中正确管理 NSManagedObjectContext?

ios - 使用用户默认值存储某物的多个值

ios - 框架和类共享名称的命名冲突

ios - 'required' initializer 'init(coder:)' 必须由 UIViewController 的子类提供

objective-c - 防止 UIAlertView 关闭

objective-c - 通过指针枚举 NSString 字符

ios - 使用自动布局(以编程方式)水平对齐 UIButton

ios - 移动位于键盘下方的内容