Ios CATextLayer仅在一段时间后显示其内容
我知道这听起来很奇怪,但问题恰恰在于:我有一个Ios CATextLayer仅在一段时间后显示其内容,ios,objective-c,view,core-graphics,cashapelayer,Ios,Objective C,View,Core Graphics,Cashapelayer,我知道这听起来很奇怪,但问题恰恰在于:我有一个ViewController,它加载一个与grandcentraldispatch异步的CSV文件(该文件表示一个直方图)。我还有一个名为historogramview的自定义视图。当控制器加载完CSV文件后,它调用historogramview上的函数invalidate。在该函数中,视图解析从文件读取的数据并创建: 有些图层表示直方图中的条形 某些CATextLayer表示条形图的标签 对于形状层没有问题,所有的工作都很好。文本层出现问题:最初只
ViewController
,它加载一个与grandcentraldispatch异步的CSV文件(该文件表示一个直方图)。我还有一个名为historogramview
的自定义视图。当控制器加载完CSV文件后,它调用historogramview
上的函数invalidate
。在该函数中,视图解析从文件读取的数据并创建:
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];
}];
}
});
}
正在主线程上调用invalidate吗?嗯。。。实际上不是。因为我传递给视图的数据是从异步文件读取加载的(感谢Grand Central Dispatch)。我在分派io读取结束时执行的代码块中调用“invalidate”。检查我的编辑。这是个问题吗?谢谢你的帮助!
- (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];
}
});
}
-(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];
}];
}
});
}