我有一个从后端填充的UITableViewController。该单元格是一个自定义单元格,它具有:
这是加载表的代码:
- (void) viewWillAppear:(BOOL)animated
{
[super viewWillAppear:animated];
[_activity startAnimating];
NSString *urlString = @"http://blablabla.com/getmydata";
NSLog(@"Loading URL=%@", urlString);
NSURL *url = [NSURL URLWithString:urlString];
NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url
cachePolicy:BACKEND_CACHE_POLICY
timeoutInterval:BACKEND_TIMEOUT_ASINC];
[NSURLConnection sendAsynchronousRequest:request
queue:[NSOperationQueue mainQueue]
completionHandler:^(NSURLResponse *response, NSData *receivedData, NSError *error) {
NSLog(@"Received data: %@", [[NSString alloc] initWithData:receivedData encoding:NSUTF8StringEncoding]);
NSError *jsonParsingError = nil;
NSDictionary *jsonData = [NSJSONSerialization JSONObjectWithData:receivedData
options:0
error:&jsonParsingError];
dispatch_async(dispatch_get_main_queue(), ^{
[_activity stopAnimating];
NSLog(@"Stop animating");
myData = [receivedData objectForKey:@"data"];
[mytable reloadData];
});
}];
}和
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
NSLog(@"Just before dequeueReusableCellWithIdentifier for row %d", indexPath.row);
CustomViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell" forIndexPath:indexPath];
NSLog(@"Just after dequeueReusableCellWithIdentifier for row %d", indexPath.row);
NSDictionary *data = [_items objectAtIndex:indexPath.row];
NSString *photo = [data objectForKey:@"photo_url"];
if([photo isKindOfClass:[NSNull class]])
photo = @"";
NSString *title = [data objectForKey:@"title"];
if([title isKindOfClass:[NSNull class]])
title = @"";
NSString *subtitle = [data objectForKey:@"subtitle"];
if([subtitle isKindOfClass:[NSNull class]])
subtitle = @"";
NSString *author = [data objectForKey:@"author"];
if([author isKindOfClass:[NSNull class]])
author = @"";
NSString *createdAt = [data objectForKey:@"created_at"];
if([createdAt isKindOfClass:[NSNull class]])
createdAt = @"";
MyImageDownloader *downloadingImage = [_downloadingImages objectForKey:indexPath];
if (downloadingImage == nil)
{
if ((photo != nil) && (![photo isEqualToString:@""]))
{
[self startImageDownload:photo forIndexPath:indexPath];
}
[cell.photoIV setImage:[UIImage imageNamed:@"noimage"]];
}
else
{
[cell.photoIV setImage:downloadingImage.image];
}
[cell.titleLb setText:title];
[cell.subtitleLb setText:subtitle];
[cell.authorLb setText:author];
[cell.createdAtLb setText:createdAt];
return cell;
}如果我运行这个,这就是输出:
2016-05-20 02:14:22.571 MyApp[7913:2037477] Loading URL=http://blablabla.com/getmydata
2016-05-20 02:14:23.233 MyApp[7913:2037477] Received data: data for 3 items.
2016-05-20 02:14:23.240 MyApp[7913:2037477] Stop animating
2016-05-20 02:14:23.242 MyApp[7913:2037477] Just before dequeueReusableCellWithIdentifier for row 0
2016-05-20 02:14:28.784 MyApp[7913:2037477] Just after dequeueReusableCellWithIdentifier for row 0
2016-05-20 02:14:28.791 MyApp[7913:2037477] Just before dequeueReusableCellWithIdentifier for row 1
2016-05-20 02:14:28.818 MyApp[7913:2037477] Just after dequeueReusableCellWithIdentifier for row 1
2016-05-20 02:14:28.821 MyApp[7913:2037477] Just before dequeueReusableCellWithIdentifier for row 2
2016-05-20 02:14:28.842 MyApp[7913:2037477] Just after dequeueReusableCellWithIdentifier for row 2
2016-05-20 02:14:28.858 MyApp[7913:2037477] Unable to simultaneously satisfy constraints.(some problems with the labels, but in the Interface Builder there are no warnings)
2016-05-20 02:14:28.873 MyApp[7913:2037477] Unable to simultaneously satisfy constraints.(some problems with the labels, but in the Interface Builder there are no warnings)
2016-05-20 02:14:28.887 MyApp[7913:2037477] Unable to simultaneously satisfy constraints.(some problems with the labels, but in the Interface Builder there are no warnings)
2016-05-20 02:14:29.645 MyApp[7913:2037477] Just before dequeueReusableCellWithIdentifier for row 0
2016-05-20 02:14:29.649 MyApp[7913:2037477] Just after dequeueReusableCellWithIdentifier for row 0
2016-05-20 02:14:29.650 MyApp[7913:2037477] Just before dequeueReusableCellWithIdentifier for row 1
2016-05-20 02:14:29.651 MyApp[7913:2037477] Just after dequeueReusableCellWithIdentifier for row 1
2016-05-20 02:14:29.652 MyApp[7913:2037477] Just before dequeueReusableCellWithIdentifier for row 2
2016-05-20 02:14:29.653 MyApp[7913:2037477] Just after dequeueReusableCellWithIdentifier for row 2
2016-05-20 02:14:29.656 MyApp[7913:2037477] Just before dequeueReusableCellWithIdentifier for row 0
2016-05-20 02:14:29.657 MyApp[7913:2037477] Just after dequeueReusableCellWithIdentifier for row 0
2016-05-20 02:14:29.658 MyApp[7913:2037477] Just before dequeueReusableCellWithIdentifier for row 1
2016-05-20 02:14:29.659 MyApp[7913:2037477] Just after dequeueReusableCellWithIdentifier for row 1
2016-05-20 02:14:29.661 MyApp[7913:2037477] Just before dequeueReusableCellWithIdentifier for row 2
2016-05-20 02:14:29.662 MyApp[7913:2037477] Just after dequeueReusableCellWithIdentifier for row 2如你所见,第一个dequeueReusableCellWithIdentifier需要5秒!!
我试图在dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0中封装NSURLConnection sendAsynchronousRequest ),但是结果是一样的。
为什么要花这么长时间?我遗漏了什么?
编辑1:
因此,最后,问题在于UILabels在单元格XIB中,我已经实现了大量的自定义单元格,它们的布局更加复杂,没有任何问题,所以这次我肯定遗漏了一些东西。
编辑2:
按照Andrew的建议,我已经在dequeueReusableCellWithIdentifier中设置了一个断点,我跳过去并暂停调试器。由于细节太低,我不太明白:
UIKit`-[UITableView dequeueReusableCellWithIdentifier:forIndexPath:]:
0x29ee6d84 <+0>: push {r4, r5, r6, r7, lr}
0x29ee6d86 <+2>: add r7, sp, #0xc
0x29ee6d88 <+4>: push.w {r8, r10, r11}
0x29ee6d8c <+8>: sub sp, #0x10
0x29ee6d8e <+10>: mov r5, r0
0x29ee6d90 <+12>: movw r0, #0xbc52
0x29ee6d94 <+16>: movt r0, #0xbb8
0x29ee6d98 <+20>: mov r10, r1
0x29ee6d9a <+22>: add r0, pc
0x29ee6d9c <+24>: mov r4, r2
0x29ee6d9e <+26>: mov r8, r3
0x29ee6da0 <+28>: ldr r1, [r0]
0x29ee6da2 <+30>: mov r0, r5
0x29ee6da4 <+32>: blx 0x2a4a2240 ; symbol stub for: CFDictionaryRemoveAllValues$shim
-> 0x29ee6da8 <+36>: mov r6, r0
0x29ee6daa <+38>: cbnz r6, 0x29ee6e1c ; <+152>
0x29ee6dac <+40>: movw r0, #0xb99c
0x29ee6db0 <+44>: movt r0, #0xbb8
0x29ee6db4 <+48>: movw r2, #0x1c36
0x29ee6db8 <+52>: movt r2, #0xbba该指令"0x29ee6da8 <+36>:mov r6,r0“在第一次执行时花费了5秒,并且在其他执行过程中非常快。
除此之外,哪个仪器可以最好地调试这个问题呢?
修好了!!
按照Andrew的建议,我复制和粘贴了堆栈跟踪,并发现时间很长是由于加载了自定义字体(这4个标签使用了在Info.plist中正确定义的自定义字体)。我所做的是为systemFont设置UILabels,并在willDisplayCell方法中设置自定义字体。这样桌子装得很快。
不好意思,我怎么才能回答这个问题呢?我应该自己回答并检查一下吗?非常感谢安德鲁!
发布于 2016-05-22 17:14:32
这个问题是由细胞内的UILabels引起的。他们使用了自定义字体,我在单元格XIB文件中设置了这种字体,所以当表第一次加载单元格时,它加载自定义字体,这需要很长时间。
我为解决这个问题所做的是:
- (void) tableView:(UITableView \*)tableView willDisplayCell:(UITableViewCell \*)cell forRowAtIndexPath:(NSIndexPath \*)indexPath
这样,加载第一个单元格的时间非常短。
发布于 2016-05-20 04:20:34
您是在代码中还是在xib文件中实现单元格的UI?如果在xib中可能是您没有在xib中配置cellId?
我还看到,只有第一个单元格被创建了很长时间,我认为在第一次初始化之后会缓存一些内容。
如果在排序板文件中配置单元格,请尝试将单元格的UI移动到Xib文件,并使用方法 of UITableView为单元格注册一个nib:
- (void)registerNib:(UINib *)nib forCellReuseIdentifier:(NSString *)identifier此外,您还可以尝试在此屏幕之前的某个地方(例如,在加载数据时)从nib中启动单元,然后该系统可以将数据保存在现金中以避免从磁盘读取文件。
此外,您还可以在使用方法加载数据时,将图像加载到后台缓存。
+ (UIImage *)imageNamed:(NSString *)name
inBundle:(NSBundle *)bundle
compatibleWithTraitCollection:(UITraitCollection *)traitCollection或
+ (UIImage *)imageNamed:(NSString *)name从文件中:
如果缓存中还没有匹配的映像对象,则此方法将定位并从磁盘或可用资产目录加载图像数据,然后返回结果对象。
https://stackoverflow.com/questions/37336105
复制相似问题