用 NSTimer 替换 usleep?

Replace usleep with NSTimer?

如何在以下代码中将 usleep 替换为 NSTimer

/**
 * DETERMINATE BAR with LABEL
 */

- (void)showDeterminateBarWithLabel:(CDVInvokedUrlCommand *)command {

    // obtain commands
    bool dim = [[command.arguments objectAtIndex:0] boolValue];
    int increment = [[command.arguments objectAtIndex:1] intValue];
    NSNumber* incrementValue = @(increment);
    NSString* text = [command.arguments objectAtIndex:2];

    // initialize indicator with options, text, detail
    self.progressIndicator = nil;
    self.progressIndicator = [MBProgressHUD showHUDAddedTo:self.webView.superview animated:YES];
    self.progressIndicator.mode = MBProgressHUDModeDeterminateHorizontalBar;
    self.progressIndicator.labelText = text;


    // Check for dim : true ? false
    if (dim == true) {
        self.progressIndicator.dimBackground = YES;
    }

    // Load Progress bar with ::incrementValue
    [self.progressIndicator showWhileExecuting:@selector(progressTask:) onTarget:self withObject:incrementValue animated:YES];

    CDVPluginResult* pluginResult = [CDVPluginResult resultWithStatus:CDVCommandStatus_OK messageAsString:@""];
    [self.commandDelegate sendPluginResult:pluginResult callbackId:command.callbackId];
}

- (void)progressTask:(NSNumber *)increment{

    // get increment value
    int _increment = [increment intValue];

    float progress = 0.0f;
    while (progress < 1.0f) {
        progress += 0.01f;
        self.progressIndicator.progress = progress;

        // increment in microseconds (100000mms = 1s)
        usleep(_increment);
    }
}

此代码取自here

你不能。 这两个完全不同,这段代码需要阻塞操作。 编辑:因为它是在后台线程上执行的。

方法-progressTask:this method, which is started on a new thread开始执行:

- (void)launchExecution {
    @autoreleasepool {
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-performSelector-leaks"
        // Start executing the requested task
        [targetForExecution performSelector:methodForExecution withObject:objectForExecution];
#pragma clang diagnostic pop
        // Task completed, update view in main thread (note: view operations should
        // be done only in the main thread)
        [self performSelectorOnMainThread:@selector(cleanUp) withObject:nil waitUntilDone:NO];
    }
}

它依赖于同步执行,使用 NSTimer 需要启动 NSRunLoop 并让它 运行 一段时间,这实际上是可能的,但是 只是不要.

提示: 如果您更喜欢 Objective-C 方法,请在几秒钟内调用 +[NSThread sleepForTimeInterval:] 并带参数。

简而言之,您不能使用来阻塞线程。用任何类型的睡眠或延迟阻塞线程都是糟糕的设计,在极少数情况下应该避免。

严禁在 iOS / OS X 应用程序中阻塞主线程。必须允许 运行 主循环 运行 否则您的应用充其量会没有响应,最坏的情况是无法运行。

相反,使用 NSTimer 定期回调您的代码以更新值。它不会阻止执行。