GUI的NSThread时序问题

时间:2011-09-26 05:00:49

标签: objective-c multithreading cocoa user-interface timing

我有一个运行无限循环的简单线程。最终,循环将每秒在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")替换书写行,它会以均匀的间隔记录。我在主线程中有另一个测试方法,它接受输入到文本字段并将其放入文本视图,这样做似乎更新了文本视图以包含子线程的最新写入。此时不应该有任何干扰它的东西,但是为了确保我到处锁定了所有东西。提前谢谢。

2 个答案:

答案 0 :(得分:3)

您应始终执行从主线程影响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]; // ?

}

答案 1 :(得分:1)

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

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