gpt4 book ai didi

Objective-C Cocoa如何在GCD中正确使用runloop

转载 作者:行者123 更新时间:2023-12-03 17:28:49 26 4
gpt4 key购买 nike

我不确定如何在可能需要停止线程的运行循环情况下正确使用 GCD。问题从一开始就开始,以及如何或在哪里使用 CGEventCallback (我的代码中没有)。停止按钮不会停止循环,而且我认为我的调度队列设置不正确——同时 while 循环造成了巨大的滞后。

我已阅读搜索中的热门问题解答,例如 thisthis ,但一个适用于 iOS,另一个不相关。有人可以告诉我如何正确执行此操作吗?

我的代码:

//.h

#import <Cocoa/Cocoa.h>

@interface AppDelegate : NSObject <NSApplicationDelegate> {

IBOutlet NSTextField *textFieldBox;
IBOutlet NSButton *stop;
}

@property (assign) IBOutlet NSWindow *window;

- (void)stop;

@end

//.m

#import "AppDelegate.h"

@implementation AppDelegate

BOOL isActive = FALSE;

- (void)applicationDidFinishLaunching:(NSNotification *)aNotification
{
[self mainMethod];
}

- (void)mainMethod {

NSLog(@"loop started");
isActive = TRUE;
[self theArbitraryNonCompliantLoop];
NSLog(@"doing other stuff");
}

- (void)stop {

isActive = FALSE;
return;
}

- (void)theArbitraryNonCompliantLoop {

dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(backgroundQueue, ^{

while (isActive) {
for (NSUInteger i = 0; i < 1000000; i++) {
[textFieldBox setStringValue:[NSString stringWithFormat:@"%lu",(unsigned long)i]];
}
}
});
}

@end

最佳答案

忽略名称,for 循环还需要测试 isActive。这将解决延迟问题。

UI 更新需要在主线程上完成,这很容易,因为您只需在主队列上安排一个 block 即可完成此操作。

- (void)theArbitraryNonCompliantLoop {

dispatch_queue_t backgroundQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(backgroundQueue, ^{

while (isActive)
{
for (NSUInteger i = 0; isActive && i < 1000000; i++)
{
dispatch_async(dispatch_get_main_queue(),
^{ [textFieldBox setStringValue:[NSString stringWithFormat:@"%lu",(unsigned long)i]] };
}
}
});
}

这里仍然存在一些问题。我认为,就目前情况而言,它将用事件淹没主线程的运行循环,因此需要进行一些限制。您还可以考虑对 inActive 实例变量进行一些同步,以防编译器通过将其拉入方法开头的寄存器来优化它。此外,由于缓存等原因,它将受到竞争条件的影响。

关于Objective-C Cocoa如何在GCD中正确使用runloop,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25242745/

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