gpt4 book ai didi

objective-c - 如何在长时间运行的循环中更新 Cocoa 中的进度条?

转载 作者:太空狗 更新时间:2023-10-30 03:46:35 25 4
gpt4 key购买 nike

我有一个 while 循环,它运行了很多秒,这就是为什么我想在该过程中更新进度条 (NSProgressIndicator),但它只在循环结束后更新一次.顺便说一句,如果我想更新标签文本,也会发生同样的情况。

我相信,我的循环阻止了该应用程序的其他事情发生。必须有另一种技术。这与线程有关吗?我在正确的轨道上吗?谁能给我一个简单的例子,如何“优化”我的应用程序?

我的应用程序是一个 Cocoa 应用程序 (Xcode 3.2.1),在我的 Example_AppDelegate.m 中有这两个方法:

// This method runs when a start button is clicked.- (IBAction)startIt:(id)sender {    [progressbar setDoubleValue:0.0];    [progressbar startAnimation:sender];    running = YES; // this is a instance variable    int i = 0;    while (running) {        if (i++ >= processAmount) { // processAmount is something like 1000000            running = NO;            continue;        }        // Update progress bar        double progr = (double)i / (double)processAmount;        NSLog(@"progr: %f", progr); // Logs values between 0.0 and 1.0        [progressbar setDoubleValue:progr];        [progressbar needsDisplay]; // Do I need this?        // Do some more hard work here...    }}// This method runs when a stop button is clicked, but as long// as -startIt is busy, a click on the stop button does nothing.- (IBAction)stopIt:(id)sender {    NSLog(@"Stop it!");    running = NO;    [progressbar stopAnimation:sender];}

我对 Objective-C、Cocoa 和带有 UI 的应用程序真的很陌生。非常感谢您提供任何有用的答案。

最佳答案

如果您正在为 Snow Leopard 构建,我认为最简单的解决方案是使用 block 和 Grand Central Dispatch。

以下代码向您展示了您的 startIt: 方法在使用 GCD 时的样子。

您的 stopIt: 方法在您编写时应该可以正常工作。它之前不工作的原因是鼠标事件发生在主线程上,因此按钮没有响应你,因为你正在主线程上工作。这个问题现在应该已经解决了,因为现在工作已经与 GCD 放在了不同的线程上。试试代码,如果它不起作用,请告诉我,我会看看我是否在其中犯了一些错误。

// This method runs when a start button is clicked.
- (IBAction)startIt:(id)sender {

//Create the block that we wish to run on a different thread.
void (^progressBlock)(void);
progressBlock = ^{

[progressbar setDoubleValue:0.0];
[progressbar startAnimation:sender];
running = YES; // this is a instance variable

int i = 0;
while (running) {
if (i++ >= processAmount) { // processAmount is something like 1000000
running = NO;
continue;
}

// Update progress bar
double progr = (double)i / (double)processAmount;
NSLog(@"progr: %f", progr); // Logs values between 0.0 and 1.0

//NOTE: It is important to let all UI updates occur on the main thread,
//so we put the following UI updates on the main queue.
dispatch_async(dispatch_get_main_queue(), ^{
[progressbar setDoubleValue:progr];
[progressbar setNeedsDisplay:YES];
});

// Do some more hard work here...
}

}; //end of progressBlock

//Finally, run the block on a different thread.
dispatch_queue_t queue = dispatch_get_global_queue(0,0);
dispatch_async(queue,progressBlock);
}

关于objective-c - 如何在长时间运行的循环中更新 Cocoa 中的进度条?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2509612/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com