Nic*_*ick 5 macos cocoa objective-c
我有一个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的应用程序的新手.非常感谢您提供任何有用的答案.
Enc*_*ada 15
如果您正在为Snow Leopard构建,我认为最简单的解决方案是使用块和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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
18638 次 |
| 最近记录: |