背景资料
目前,我正在使用以下代码为UITableViewCell
中的每个UITableView
设置文本:
方案A:cell.textLabel.attributedText = [news formattedSubject];
但是,请考虑是否要为formattedSubject
定义添加一个参数,只是一个整数参数,因此代码现在为:
方案B:cell.textLabel.attributedText = [news formattedSubject:1];
每个表格视图单元格中的文本大约3-5行,并从外部来源读取并通过JSON进行解析。这是所需结果的图,这是方案A 中发生的情况:
方案A流程图:
图片A仅显示应用仍在加载JSON数据时获得的默认空UITableView
。应用程序检索并解析了这些数据之后,便将数据填充到UITableView
中,从而生成图像B。这是期望的(和预期的)结果。
但是,如果将参数添加到formattedSubject
,则会获得以下流程图:
方案B流程图:
图像A再次显示默认的UITableView
。但是,问题出在图像B中。 在图像B中,数据已被解析,但是尚未通过formattedSubject
正确格式化,因此导致单个,水平狭窄且较长的未格式化文本行。 在几分之一秒后,该应用程序看起来像图像C,最终结果显示了经过解析的格式化数据。
我的问题:
我所做的唯一更改是在formattedSubject
中添加了一个参数。 也就是说,我将-(NSAttributedString*)formattedSubject {
更改为-(NSAttributedString*)formattedSubject:(int)state {
。 没关系,formattedSubject
中没有任何东西实际上使用了state
整数,我仍然从场景B中得到结果。
此更改似乎使代码运行速度更慢。它在解析数据与格式化并在UITableView
中显示数据之间创建了一个延迟。我很好奇这是为什么,以及如何解决/避免这个问题。
除了美学上的问题外,场景B中的情况还会在用户到达UITableView
的末尾时干扰我自动加载新数据。由于文本水平缩小,因此最后一行数据在首次加载时即刻显示在UITableView
中,即,从而导致在应用程序启动时两次检索到数据。
我距离编码专家还很遥远,因此,对我来说,在NSAttributedString
中简单地添加参数会产生上述延迟是绝对没有道理的。如果有人可以,我将不胜感激:
非常感谢您阅读本文,我们欢迎任何评论/帮助。
编辑1:@ Vijay-Apple-Dev.blogspot.com,@txulu
这是我的
formattedSubject
代码:-(NSAttributedString*)formattedSubject:(int)state {
if(formattedSubject!=nil) return formattedSubject;
NSDictionary *boldStyle = [[NSDictionary alloc] init];
if(state==1) {
boldStyle = @{NSFontAttributeName:[UIFont fontWithName:@"Helvetica-Bold" size:16.0],NSForegroundColorAttributeName:[UIColor colorWithRed:0.067 green:0.129 blue:0.216 alpha:1.0]};
}
else {
boldStyle = @{NSFontAttributeName:[UIFont fontWithName:@"Helvetica-Bold" size:16.0],NSForegroundColorAttributeName:[UIColor whiteColor]};
}
NSDictionary* normalStyle = @{NSFontAttributeName: [UIFont fontWithName:@"Helvetica" size:14.0]};
NSMutableAttributedString* articleAbstract = [[NSMutableAttributedString alloc] initWithString:subject];
[articleAbstract setAttributes:boldStyle range:NSMakeRange(0, subject.length)];
[articleAbstract appendAttributedString:[[NSAttributedString alloc] initWithString:@"\n"]];
int startIndex = [articleAbstract length];
NSTimeInterval _interval=[datestamp doubleValue];
NSDate *date = [NSDate dateWithTimeIntervalSince1970:_interval];
NSDateFormatter *_formatter=[[NSDateFormatter alloc]init];
[_formatter setDateFormat:@"MM/dd/yy"];
NSString* description = [NSString stringWithFormat:@"By %@ on %@",author,[_formatter stringFromDate:date]];
[articleAbstract appendAttributedString:[[NSAttributedString alloc] initWithString: description]];
[articleAbstract setAttributes:normalStyle range:NSMakeRange(startIndex, articleAbstract.length - startIndex)];
formattedSubject = articleAbstract;
return formattedSubject;
}
请注意,正如我之前说的,即使我实际上没有使用state
参数,我仍然会得到相同的结果。这是我的
cellForRowAtIndexPath
代码:- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
}
News *news = newsArray[indexPath.row];
NSIndexPath *selectedIndexPath = [tableView indexPathForSelectedRow];
if([selectedIndexPath isEqual:indexPath]) {
cell.textLabel.attributedText = [news formattedSubject:1];
}
else {
cell.textLabel.attributedText = [news formattedSubject:0];
}
cell.textLabel.numberOfLines = 0;
cell.textLabel.lineBreakMode = NSLineBreakByWordWrapping;
UIView *selectedBackgroundViewForCell = [UIView new];
[selectedBackgroundViewForCell setBackgroundColor:[UIColor colorWithRed:0.169 green:0.322 blue:0.525 alpha:1.0]];
cell.selectedBackgroundView = selectedBackgroundViewForCell;
cell.textLabel.highlightedTextColor = [UIColor whiteColor];
if (indexPath.row == [newsArray count] - 1) {
[self parseJSON];
}
return cell;
}
请让我知道是否可以发布其他任何有帮助的信息。编辑2:
我不确定是否存在性能问题。经过进一步测试,我倾向于认为,在方案A中,该应用程序先加载并格式化单元格数据,然后再将其显示在上,而在方案B中,该应用程序加载数据,并以
UITableViewCell
进行显示,然后先将的数据显示为格式它,这产生了我上面详细介绍的问题。有人在我的
parseJSON
方法中调出了代码,因此我将其发布在这里以供参考。如您所见,我确实实现了多线程,以防止数据加载滞后于应用程序。-(void)parseJSON
{
loading.alpha = 1;
loading.image = [UIImage imageNamed:@"loading.png"];
activityIndicator.alpha = 1;
timer = [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(checkLoading) userInfo:nil repeats:YES];
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(queue, ^{
parseNumber = parseNumber + 1;
int offset = parseNumber*20-1;
NSString *URLString = [NSString stringWithFormat:@"http://feedurl.com/feed.php?offset=%d",offset];
NSURL *url=[NSURL URLWithString:URLString];
NSData *data=[NSData dataWithContentsOfURL:url];
NSError* error;
if(data!=nil) {
json = [NSJSONSerialization JSONObjectWithData:data options: NSJSONReadingMutableContainers error: &error];
for(NSDictionary *newsInfo in json) {
News *newsList = [[News alloc] init];
newsList.thread = newsInfo[@"thread"];
newsList.author = newsInfo[@"author"];
newsList.subject = newsInfo[@"subject"];
newsList.body= newsInfo[@"body"];
newsList.datestamp = newsInfo[@"datestamp"];
[jsonTemp addObject:newsList];
}
newsArray = jsonTemp;
}
dispatch_sync(dispatch_get_main_queue(), ^{
if(data!=nil) {
[newsTable reloadData];
}
else {
activityIndicator.alpha = 0;
loading.image = [UIImage imageNamed:@"error.png"];
[self startTimer];
}
});
});
}
最佳答案
编辑:
好的,调用[news formattedSubject]
而不是[news formattedSubject:1]
有所不同。第一个就像做news.formattedSubject
一样,这就是访问快速返回ivar的formattedSubject属性。第二个调用较复杂的formattedSubject:
方法,该方法执行您发布的代码的速度较慢。
原始:
您的代码看起来不错,除了一些小细节,例如:
NSDictionary *boldStyle = [[NSDictionary alloc] init];
不需要,因为您是在之后分配的:
boldStyle = @{NSFontAttributeName ...}
另外,我猜可能导致您的问题的原因是:
if (indexPath.row == [newsArray count] - 1) {
[self parseJSON];
}
在cellForRowAtIndexPath:内部调用此函数可能会导致严重的性能问题。如果此方法做了很多工作并且没有在后台执行,则可能导致您提到的延迟。根据经验,永远不要在主线程中进行网络/数据处理(cellForRowAtIndexPath将始终由系统在该线程中调用)。
关于ios - 传递参数会使代码运行“更慢”吗?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22320930/