GUI 的 NSThread 计时问题

发布于 2024-12-06 17:50:08 字数 512 浏览 0 评论 0原文

我有一个运行无限循环的简单线程。最终,循环将每秒检查 USB 端口上的串行数据数千次,但目前,它只是每秒向 NSTextView 的自定义类写入一次内容。

int i;
for (i=1; i>0; i++)
{
    [lock lock];
    [[self textStorage] replaceCharactersInRange:NSMakeRange([[self textStorage] length], 0) withString:@"test\n"];
    [lock unlock];
    sleep(1);
}

问题是它写得非常零散。它会做一两个,然后等待十秒钟,然后立即吐出十个。如果我用 NSLog(@"test") 替换写入行,它会以均匀的间隔记录。我在主线程中有另一个测试方法,它接受文本字段的输入并将其放入文本视图中,这样做似乎会更新文本视图以包含子线程的最新写入。无论如何,此时不应该有任何东西干扰它,但为了确定起见,我已经锁定了所有地方的所有东西。提前致谢。

I have a simple thread that runs an infinite loop. Eventually, the loop will check for serial data at a USB port a few thousand times per second, but at the moment, it just writes something to a custom class of NSTextView once every second.

int i;
for (i=1; i>0; i++)
{
    [lock lock];
    [[self textStorage] replaceCharactersInRange:NSMakeRange([[self textStorage] length], 0) withString:@"test\n"];
    [lock unlock];
    sleep(1);
}

The issue is that it writes really sporadically. It will do one or two, then wait ten seconds and spit ten of them out at once. If I replace the writing line with an NSLog(@"test"), it logs at nice even intervals. I have another test method in the main thread that accepts input into a text field and puts it into the text view, and doing this seems to update the text view to include the child thread's most recent writes. There shouldn't be anything interfering with it at this point anyway, but I've locked everything everywhere just to be sure. Thanks in advance.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

幸福丶如此 2024-12-13 17:50:08

您应该始终从主线程执行影响 UI 的操作。您可以让子线程创建一个保存结果的临时对象,然后使用 performSelectorOnMainThread:withObject:waitUntilDone: 调用另一个方法来对主线程进行必要的修改。

NSString * const MDResultKey = @"MDResult";

- (void)someMethod {
    // 
    int i;
    for (i=1; i>0; i++) {
         // if necessary, create an object to hold results
         NSDictionary *results = [NSDictionary 
               dictionaryWithObjectsAndKeys:@"test", MDResultKey, nil];

         [self performSelectorOnMainThread:@selector(updateUIWithResults:) 
                  withObject:results waitUntilDone:NO];

         sleep(1);
    }
}


- (void)updateUIWithResults:(NSDictionary *)results {
    NSString *result = [results objectForKey:MDResultKey];
    [lock lock]; // ?
    [[self textStorage] replaceCharactersInRange:
           NSMakeRange([[self textStorage] length], 0) withString:result];
    [lock unlock]; // ?

}

You should always perform operations that affect the UI from the main thread. You can have the child thread create a temporary object that holds the results, and then use performSelectorOnMainThread:withObject:waitUntilDone: to call another method that will do the necessary modifications on the main thread.

NSString * const MDResultKey = @"MDResult";

- (void)someMethod {
    // 
    int i;
    for (i=1; i>0; i++) {
         // if necessary, create an object to hold results
         NSDictionary *results = [NSDictionary 
               dictionaryWithObjectsAndKeys:@"test", MDResultKey, nil];

         [self performSelectorOnMainThread:@selector(updateUIWithResults:) 
                  withObject:results waitUntilDone:NO];

         sleep(1);
    }
}


- (void)updateUIWithResults:(NSDictionary *)results {
    NSString *result = [results objectForKey:MDResultKey];
    [lock lock]; // ?
    [[self textStorage] replaceCharactersInRange:
           NSMakeRange([[self textStorage] length], 0) withString:result];
    [lock unlock]; // ?

}
黑色毁心梦 2024-12-13 17:50:08

我个人对于在后台线程上调用 NSTextStorage 上的任何内容都非常谨慎。我认为 NSTextView 会对任何 NSTextStorage 更改做出反应,并且非主线程上的任何 UI 代码都会出现不可预测的问题。

我只需将新字符串发送到主线程并在那里调用 -replaceCharactersInRange:

I'd personally be pretty wary of calling anything on an NSTextStorage on a background thread. I think NSTextView reacts to any NSTextStorage changes, and any UI code on a non-main thread is going to have unpredictable problems.

I would just send the new string to the main thread and call -replaceCharactersInRange: there.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文