我知道这听起来很奇怪,但问题恰恰在于:我有一个ViewController
加载了一个与Grand Central Dispatch异步的CSV文件(该文件表示一个直方图)。我还有一个名为的自定义视图HistogramView
。控制器完成CSV文件的加载后,将invalidate
在上调用一个函数HistogramView
。在该函数中,视图解析从文件读取的数据并创建:
对于形状层没有问题,所有方法都很好。文本层出现问题:最初仅显示背景。文本仅在几秒钟后出现:-/,这很奇怪。这是invalidate
函数的代码(正如我所说的,该函数在自定义视图中)。
-(void)invalidate{
float tempX = 0;
float tempHeight = 0;
NSArray *data;
if([self.dataSource getHistogramData] != nil){
data = [self.dataSource getHistogramData];
tempX = [self getStartingX];
[self getDataMaxValue];
for (int i=0; i<[data count]; i+=2) {
//THE SHAPE LAYER THAT REPRESENTS AN HISTOGRAM BAR
tempHeight = [self uniformValue:[[data objectAtIndex:i+1] intValue]];
CAShapeLayer *rectLayer = [CAShapeLayer layer];
CGRect rect = CGRectMake(tempX, tempHeight, barWidth, height - tempHeight - spaceForLabels);
rectLayer.path = CGPathCreateWithRect(rect, nil);
[rectLayer setBackgroundColor:[UIColor colorWithRed:1 green:1 blue:1 alpha:1].CGColor];
[self.layer addSublayer:rectLayer];
//THE TEXT LAYER THAT REPRESENTS A LABEL FOR THE BAR
CATextLayer *textLayer = [CATextLayer layer];
textLayer.frame = CGRectMake(tempX, height - spaceForLabels, barWidth, spaceForLabels);
textLayer.font = CFBridgingRetain([UIFont boldSystemFontOfSize:18].fontName);
textLayer.fontSize = 18;
textLayer.foregroundColor = [UIColor redColor].CGColor;
textLayer.backgroundColor = [UIColor yellowColor].CGColor;
textLayer.alignmentMode = kCAAlignmentCenter;
textLayer.string = @"example";
[self.layer addSublayer:textLayer];
tempX += barWidth + spaceBetweenBars;
}
}
}
如您所见,我以相同的方式在同一点创建条形图和标签。先感谢您。
编辑:在我的视图控制器中,我以viewDidLoad
这种方式进行方法内的工作:
- (void)viewDidLoad {
[super viewDidLoad];
//create the channel with which read the CSV file
dispatch_io_t ch = dispatch_io_create_with_path(DISPATCH_IO_STREAM, [[[NSBundle mainBundle] pathForResource:@"histogram1" ofType:@"csv"] UTF8String], O_RDONLY, 0, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), nil);
//read the CSV file async with GCD
[self readCSVFile:ch];
//set the delegates for the histogram view
self.histogramView.delegate = self;
self.histogramView.dataSource = self;
}
-(void)readCSVFile:(dispatch_io_t)ch{
//the string that represents the content of CSV file
NSMutableString __block *stringFromData;
//read the whole file
dispatch_io_read(ch, 0, SIZE_MAX, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(bool done, dispatch_data_t dataRead, int error) {
if(!error && !done){
//convert from dispatch_data_t to NSString
size_t dataSize = dispatch_data_get_size(dataRead);
stringFromData = [[NSMutableString alloc]initWithCapacity:dataSize];
dispatch_data_apply(dataRead, ^bool(dispatch_data_t region, size_t offset, const void *buffer, size_t size) {
[stringFromData appendFormat:@"%.*s", (unsigned int)size, buffer];
return true;
});
}else{
dispatch_io_close(ch, 0);
data = [stringFromData componentsSeparatedByCharactersInSet:
[NSCharacterSet characterSetWithCharactersInString:@"\n,"]];
//AND NOW I CALL INVALIDATE ON THE VIEW
[self.histogramView invalidate];
}
});
}
好的我明白了。我要感谢rdelmar,他的建议为我指出了问题所在。如他所说,invalidate
不是从主线程调用,而是从后台线程(读取文件的线程)调用。这是错误的,因为必须从主线程更新视图。因此,我仅通过invalidate
这种方式调用方法来解决问题:
-(void)readCSVFile:(dispatch_io_t)ch{
//the string that represents the content of CSV file
NSMutableString __block *stringFromData;
//read the whole file
dispatch_io_read(ch, 0, SIZE_MAX, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(bool done, dispatch_data_t dataRead, int error) {
if(!error && !done){
//convert from dispatch_data_t to NSString
size_t dataSize = dispatch_data_get_size(dataRead);
stringFromData = [[NSMutableString alloc]initWithCapacity:dataSize];
dispatch_data_apply(dataRead, ^bool(dispatch_data_t region, size_t offset, const void *buffer, size_t size) {
[stringFromData appendFormat:@"%.*s", (unsigned int)size, buffer];
return true;
});
}else{
dispatch_io_close(ch, 0);
data = [stringFromData componentsSeparatedByCharactersInSet:
[NSCharacterSet characterSetWithCharactersInString:@"\n,"]];
//HERE IS THE SOLUTION
[[NSOperationQueue mainQueue]addOperationWithBlock:^{
[self.histogramView invalidate];
}];
}
});
}
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句