开发者

NSThread Timing Problem with GUI

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 wai开发者_如何学Pythont 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.


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]; // ?

}


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜