gpt4 book ai didi

cocoa - 工作表和长时间运行的任务

转载 作者:行者123 更新时间:2023-12-03 17:44:00 25 4
gpt4 key购买 nike

我需要在用户单击按钮后运行一个复杂(即很长)的任务。该按钮打开一个工作表,并使用dispatch_async和其他Grand Central Dispatch东西启动长时间运行的操作。

我已经编写了代码,它工作正常,但我需要帮助来了解我是否正确完成了所有操作,或者我是否忽略了(由于我的无知)任何潜在的问题。

用户单击按钮并打开工作表,该 block 包含长任务(在本示例中,它仅运行 for(;;) 循环该 block 还包含任务完成时关闭工作表的逻辑。

-(IBAction)openPanel:(id)sender {
[NSApp beginSheet:panel
modalForWindow:[self window]
modalDelegate:nil
didEndSelector:NULL
contextInfo:nil];

void (^progressBlock)(void);
progressBlock = ^{

running = YES; // this is a instance variable

for (int i = 0; running && i < 1000000; i++) {
[label setStringValue:[NSString stringWithFormat:@"Step %d", i]];
[label setNeedsDisplay: YES];
}
running = NO;
[NSApp endSheet:panel];
[panel orderOut:sender];

};

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

该面板包含一个“停止”按钮,允许用户在任务完成之前停止任务

-(IBAction)closePanel:(id)sender {
running = NO;
[NSApp endSheet:panel];
[panel orderOut:sender];
}

最佳答案

此代码存在一个潜在问题,即它设置状态文本的值。基本上,AppKit 中的所有对象都只允许从主线程调用,否则可能会以奇怪的方式中断。您可以从运行全局队列的任何线程调用标签上的 setStringValue:setNeedsDisplay: 方法。要解决这个问题,您应该像这样编写循环:

for (int i = 0; running && i < 1000000; i++) {
dispatch_async(dispatch_get_main_queue(), ^{
[label setStringValue:[NSString stringWithFormat:@"Step %d", i]];
[label setNeedsDisplay: YES];
});
}

这将按照 AppKit 的预期从主线程设置标签文本。

关于cocoa - 工作表和长时间运行的任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4645481/

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