用 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 定期回调您的代码以更新值。它不会阻止执行。
如何在以下代码中将 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 定期回调您的代码以更新值。它不会阻止执行。