似乎在使用了一点之后,我的应用程序在UITableViewController
. 有一些非常密集的方法,但一旦完成,就没有理由影响应用程序的整体性能。
我一直在使用仪器来确定它可能是什么,但事实证明它非常不确定。首先,我无法通过一种方法重新创建问题,它似乎只是从一般用法中发生的。cellForRowAtIndexPath
根据线程使用情况,使用 CPU 的主要内容是我的。虽然我确实做了很多计算,但它并不能解释两件事。1)为什么这个问题会随着时间的推移而发展。当我第一次启动应用程序时,我可以上下滚动TableViewController
几次,一切都非常流畅。2)即使我删除了除 3 或 4 个单元格之外的所有单元格,仍然没有响应。
另一个观察结果是,modal ViewController
当应用程序第一次加载时,a 有一个非常流畅的动画,但最终会出现这种可怕的锯齿状动画,有时只有 1 或 2 帧,后来。同样,有几个相当复杂的计算解除这个 Modal (包括一个 managedObjectContext 保存),它确实接近揭示UITableView
下面(意思是 some cellForRowAtIndexPath
)但是没有办法单独这两个东西可以使动画虚拟0 帧/秒。所有这一切让我相信资源正在被耗尽并且不会返回。现在可悲的是,我对 iOS 环境的了解还不够,无法确定下一个假设,但这里有:
记忆。简单地说,不可能真的是这样吧?尽管我的应用程序非常占用内存,并且包含大量图像,但我很确定 iOS 会在 RAM 开始用完时将其从 RAM 中删除。最重要的是,诊断显示当我在应用程序中遇到大量延迟时,我有 50MB 的可用空间。
中央处理器。我认为可能是某些东西耗尽了我所有的 CPU,就像我上次遇到性能问题时一样(我调用了一个方法的无限循环,哎呀)但是,该应用程序似乎只在需要时才使用 CPU。换句话说,当应用程序空闲时,它会回到 0 使用量。只是为了解释这有多重要;如果作为资源的 CPU 被某种东西吞噬了,那么它就可以解释为什么
cellForRowAtIndexPath
随着时间的推移而挣扎。但是,由于它没有被吃掉,因此没有理由长时间使用该应用程序会导致cellForRowAtIndexPath
使用过多的 CPU。因此,我看不出我的问题是如何由 CPU 占用引起的。
当然,因为这是我能想到的仅有的两种资源,我完全被难住了。我不知道为什么应用程序会随着时间的推移变得缓慢。实际上,我看不到它是如何成为代码的,因为应用程序在首次启动时运行良好,而且当似乎还剩很多时,我看不到它如何成为资源。
由于我是 Objective-C/iOS 开发的新手,我怀疑我缺少一些东西。如果您能帮助我识别它,我将不胜感激。
更新:发布我的代码cellForRowAtIndexPath
和willDisplayCell
:
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
{
myEntityForConfigureCell = [self.fetchedResultsController objectAtIndexPath:indexPath];
searchResultForConfigureCell = [searchResults objectForKey:myEntityForConfigureCell.trackId];
// Example of how I fill in cell information. There are far more than shown.
nameLabelForConfigureCell = (UILabel *)[cell viewWithTag:1001];
nameLabelForConfigureCell.text = myEntityForConfigureCell.name;
genreLabelForConfigureCell = (UILabel *)[cell viewWithTag:1002];
genreLabelForConfigureCell.text = searchResultForConfigureCell.genre;
// Example of how I do the ImageViews using AFNetworking
imageForConfigureCell = (UIImageView *)[cell viewWithTag:1000];
[imageForConfigureCell setImageWithURL:[NSURL URLWithString: searchResultForConfigureCell.artworkURL60]];
imageForConfigureCell.layer.cornerRadius = 9.4;
imageForConfigureCell.layer.masksToBounds = YES;
// The RateView for showing a start rating
rateViewForConfigureCell = [[DYRateView alloc] initWithFrame:CGRectMake(73, 44, 75, 12) fullStar:[UIImage imageNamed:@"StarFullSmall.png"] emptyStar:[UIImage imageNamed:@"StarEmptySmall.png"]];
rateViewForConfigureCell.rate = [searchResultForConfigureCell.rating floatValue];
rateViewForConfigureCell.alignment = RateViewAlignmentLeft;
[cell.contentView addSubview:rateViewForConfigureCell];
// Setting Sections for all Core Data entries only if BOOL isLoading is YES, but **has** finished downloading informaton, i.e. just before completion.
if ([searchResults count] == [fetchedResultsController.fetchedObjects count]) {
if (isLoading) {
NSLog(@"Is loading so Setting Sections");
isLoading = NO;
[self cycleThroughEntriesAndSetSection];
}
else if (!isLoading){
[loadingHudView removeFromSuperview];
}
}
}
现在为willDisplayCell
:
-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
myEntityForDisplayCell = [self.fetchedResultsController objectAtIndexPath:indexPath];
searchResultForDisplayCell = [searchResults objectForKey:myEntityForDisplayCell.trackId];
UILabel *currentPrice = (UILabel *)[cell viewWithTag:1003];
if ([myEntityForDisplayCell.price1 floatValue] == [searchResultForDisplayCell.price2 floatValue]) {
currentPrice.textColor = [UIColor blackColor];
}
else if ([myEntityForDisplayCell.price1 floatValue] > [searchResultForDisplayCell.price2 floatValue])
{
currentPrice.textColor = [UIColor colorWithRed:0 green:0.9 blue:0 alpha:1];
}
else if ([myEntityForDisplayCell.price1 floatValue] < [searchResultForDisplayCell.price2 floatValue])
{
currentPrice.textColor = [UIColor redColor];
}
cell.backgroundColor = nil;
if (isLoading) {
loadingHudView.numOne = [searchResults count];
loadingHudView.numTwo = [fetchedResultsController.fetchedObjects count];
[loadingHudView setNeedsDisplay];
}
if ([searchResults count] == [fetchedResultsController.fetchedObjects count]) {
[loadingHudView removeFromSuperview];
if ([myEntityForDisplayCell.price1 floatValue] < [searchResultForDisplayCell.price2 floatValue]) {
cell.backgroundColor = nil;
}
else
{
cell.backgroundColor = [UIColor colorWithRed:1 green:0.85 blue:0 alpha:0.45];
}
}
}
更新 2:使用分析器工具找到了一些东西。我不完全确定它是如何泄漏的,但无论如何都会发生。
SearchResult *searchResult = [[SearchResult alloc] init];
for (id i in fetchedResultsController.fetchedObjects) {
MyEntity *myEntity = i;
searchResult = [searchResults objectForKey:myEntity.id];
每次将新实体添加到 Core Data 数据库时,这段代码可能会执行一次,即不是特别频繁。