毫无例外地在[textView insertText:]上停止执行! [英] execution stops on [textView insertText:] without exception!
问题描述
我正在编写一个非常简单的OSX应用程序.在此应用程序中,有一个主线程不断更新某些内容,然后计算一些统计信息并将其打印在textView上.
I am writing a very simple OSX app. In this app, there is a main thread that keeps updating some stuff, then calculates some statistics and prints them on a textView.
在开发过程中,我使用了相同的接收到的IBAction来执行此循环.我一切正常,然后切换到NSThread以防止UI在计算时锁定.
While developing, i used the same received IBAction to perform this cycle. I got it all working, then switched to NSThread to prevent the UI from locking while computing.
我这样做之后,该应用程序开始运行很少的周期(大约7-8),然后整个应用程序冻结,没有任何异常.通过调试,我注意到在尝试在textView上打印统计信息时,它冻结了,我对如何解决此问题一无所知.如果不在线程内,它就可以工作...有人可以帮忙吗?下面的代码.在此先感谢:)
As soon as i did that, the app started running very few cycles (about 7-8), then the whole app freezes without any exception. By debugging, i noticed that it freezes when trying to print statistics on the textView, and i have absolutely no clue about how to solve this. It works if not inside a thread... Anyone can help? Code below. Thanks in advance :)
-(IBAction) Evolve:(id)sender{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[NSThread detachNewThreadSelector:@selector(Evolve) toTarget:self withObject:nil];
[pool drain];
}
这是整个周期
-(void) Evolve{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
srandom(time(NULL));
//Tag 0: Minimo, Tag 1: Massimo
int tagMinMax = [MinMax selectedTag];
//Tag 0: Rimpiazza sempre, Tag 1: Rimpiazza solo se migliori
int tagRimpiazzo = [[Rimpiazzo selectedItem] tag];
int PopNum = [tf_popNum intValue];
int maxGen = [tf_maxGen intValue];
int target = [tf_targetVal intValue];
int chromosomeLength = [tf_chromosomeLength intValue];
Environment *env = [[Environment alloc] init];
NSMutableArray *pop = [[NSMutableArray alloc] init];
for (int i = 0; i < PopNum; i++) {
[pop addObject:[[Individual alloc] initWithRandomGenesWithChromosomeLength:chromosomeLength]];
}
[env setPopulation:pop];
[pop release];
BOOL earlyBestFound = NO;
Individual *earlyBest = nil;
int i=0;
float best, avg;
while (i<maxGen && !earlyBestFound) {
NSLog(@"while");
NSArray *parents = [env selectParents];
NSLog(@"parents selected");
NSMutableArray *offspring = [[NSMutableArray alloc] init];
for (int i = 0; i < [parents count]; i+=2) {
if (i+1<[parents count]) {
NSLog(@"beginning SEX");
Individual *parent1 = [parents objectAtIndex:i];
Individual *parent2 = [parents objectAtIndex:i+1];
NSArray *children = [parent1 kCrossOverWithOtherIndividual:1 individual:parent2];
Individual *child1 = [children objectAtIndex:0];
Individual *child2 = [children objectAtIndex:1];
NSLog(@"children born");
if (tagRimpiazzo!=0) {
if (([child1 fitness] > [parent1 fitness] && tagMinMax == 0)||([child1 fitness] < [parent1 fitness] && tagMinMax == 1)) {
child1 = parent1;
}
if (([child2 fitness] > [parent2 fitness] && tagMinMax == 0)||([child2 fitness] < [parent2 fitness] && tagMinMax == 1)) {
child2 = parent2;
}
}
NSLog(@"Replacement happened");
[offspring addObject:child1];
[offspring addObject:child2];
}
}
NSLog(@"Calculating statistics");
avg = 0;
for(Individual *X in offspring){
if (([X fitness] > best && tagMinMax == 1)||([X fitness] < best && tagMinMax == 0)) {
best = [X fitness];
}
avg += [X fitness];
if ([X fitness]==target) {
earlyBestFound = YES;
earlyBest = X;
}
}
avg = avg/(float)PopNum;
[env setPopulation:offspring];
NSLog(@"Releasing some memory");
[offspring release];
NSLog(@"Printing statistics");
NSString *toPrint = [NSString stringWithFormat:@"Fine generazione: %d avg: %.2f best: %.2f \r\n", i,avg,best];
[textView insertText:toPrint];
i++;
}
NSLog(@"Fine");
NSString *toPrint = [NSString stringWithFormat:@"Fine! best: %.2f - avg: %.2f \r\n", i,avg,best];
[textView insertText:toPrint];
[env release];
[pool drain];
}
P.S.抱歉,如果英语不够完美,我是意大利语:)
P.S. Sorry if the english's not perfect, i'm italian :)
推荐答案
您的应用程序崩溃了,因为您正在从后台线程访问 textView
.UI对象只能从主线程访问.
Your application is crashing because you are accessing textView
from a background thread. UI objects may only be accessed from the main thread.
要解决此问题,您需要将 textview 更新转发到主 UI 线程.您可以使用 -performSelectorOnMainThread:
方法执行此操作.例如:
To solve the problem, you will need to forward you textview updates to the main UI thread. You can do this using the -performSelectorOnMainThread:
method. For example:
[textView performSelectorOnMainThread:@selector(insertText:)
withObject:toPrint
waitUntilDone:YES];
这篇关于毫无例外地在[textView insertText:]上停止执行!的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!