【问题标题】:iOS: Debugging simple UI lags (based on CoreData I guess)iOS:调试简单的 UI 滞后(我猜是基于 CoreData)
【发布时间】:2014-01-20 21:28:16
【问题描述】:

我目前正在测试我的应用程序,尤其是在 iPhone 4s 上。并且一些简单的 UI 任务似乎滞后和延迟,例如在集合视图中选择图像或更改 UI 复选框的状态。有没有更好的方法来做到这一点?我需要在这里做一些异步的事情吗?如果某些内容发生了变化,CoreData 中的属性也会发生变化,但这会那么慢吗?

CollectionView(图片名称都保存在viewdidload的数组中):

- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *identifier = @"IconCell";

    IconSelectionCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:identifier forIndexPath:indexPath];

    cell.iconImageView.image = [UIImage imageNamed:[self.icons objectAtIndex:indexPath.row]];

    return cell;
}

#pragma mark Collection View Delegate methods
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
{
    self.mainCategory.icon = [self.icons objectAtIndex:indexPath.row];
}

以 UISwitch 为例:

- (IBAction)liveBudgetSwitched:(id)sender
{
    self.spendingCategory.liveBudget = [NSNumber numberWithBool: self.liveBudgetSwitch.on];
}

【问题讨论】:

  • 您是否在 Core Data 中保存图像?它们有多大?
  • 不,只是字符串。如您在此处看到的: cell.iconImageView.image = [UIImage imageNamed:[self.icons objectAtIndex:indexPath.row]];只是字符串被保存和使用。尤其是 UISwitch 很奇怪不是吗?有时(并非总是)当您单击它时,它会保持相同的状态大约 1 秒钟,然后才会切换。很混乱。而且 coredata 连接应该没问题,因为我使用了苹果的模板并且根本没有改变任何东西。也许它与当前的另一个问题有关:stackoverflow.com/questions/20900310/…

标签: ios objective-c core-data uicollectionview uiswitch


【解决方案1】:

使用该代码很难为您提供帮助。它可以是很多东西。也许您的图像比应有的大得多,也许您的单元格在一个标签或背景中有阴影,谁知道呢?

因此,您需要先找出问题所在。

在这种情况下,您可以打开仪器并分析问题是 CPU 还是 GPU。

您可以使用 Time Profiler 了解问题是否出在 CPU,而对于 GPU,您可以使用 Core Animation。

在时间分析器中尝试检查 CPU 消耗最多的位置。您可以使用一些选项来帮助您专注于代码。您可以仅显示objective-c隐藏系统库

在 Core Animation 中,您可以使用许多选项来检查您可能遇到的一些问题。这些选项是:

  • 颜色混合图层 - 突出显示您有多个图层,GPU 需要混合这些图层
  • 颜色变为绿色而未变为红色 - 如果是绿色,则很好,如果是红色,则说明您没有缓存图像,并且这些图像被重新生成了很多次(当您例如有阴影)
  • 复制图像的颜色 - 如果它显示为蓝色,则核心动画在应该发送指针时将图像的副本发送到渲染服务器
  • Flash 更新区域 - 重绘视图时显示为黄色

【讨论】:

  • 非常感谢您的提示。我将在接下来的两天内检查并再次发表评论。但这确实是一个奇怪的问题,因为在第一次尝试时一切都很顺利。所以我想也许我注销了一些不应该注销的东西,或者一些参考资料丢失了,或者其他什么。因为我没有在数据库中保存图像或大的东西。只是字符串应该显示什么图像..
  • @MichiZH 你发现问题了吗?
【解决方案2】:

是的,我做到了。滞后是由于 NSFetchedResultsController 不断监控,即使我的视图不可见。我刚刚使用了我用于表格视图中所有用户驱动更改的属性,以阻止控制器在我的视图不在屏幕上时进行侦听:

- (void)viewWillDisappear:(BOOL)animated
{
    [super viewWillDisappear:animated];
    self.suspendAutomaticTrackingOfChangesInManagedObjectContext = YES;
}

-(void)viewDidDisappear:(BOOL)animated
{
    [super viewDidDisappear:animated];
    self.suspendAutomaticTrackingOfChangesInManagedObjectContext = YES;
}

- (void)viewWillAppear:(BOOL)animated
{
    [super viewWillAppear:animated];
    self.suspendAutomaticTrackingOfChangesInManagedObjectContext = NO;
}


#pragma mark - NSFetchedResultsControllerDelegate
- (void)controllerWillChangeContent:(NSFetchedResultsController *)controller
{
    if (self.suspendAutomaticTrackingOfChangesInManagedObjectContext) return;

    [self.tableView beginUpdates];
}

- (void)controller:(NSFetchedResultsController *)controller
  didChangeSection:(id <NSFetchedResultsSectionInfo>)sectionInfo
           atIndex:(NSUInteger)sectionIndex
     forChangeType:(NSFetchedResultsChangeType)type
{
    if (self.suspendAutomaticTrackingOfChangesInManagedObjectContext) return;

    switch(type) {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}


- (void)controller:(NSFetchedResultsController *)controller
   didChangeObject:(id)anObject
       atIndexPath:(NSIndexPath *)indexPath
     forChangeType:(NSFetchedResultsChangeType)type
      newIndexPath:(NSIndexPath *)newIndexPath
{
    if (self.suspendAutomaticTrackingOfChangesInManagedObjectContext) return;

    switch(type) {
        case NSFetchedResultsChangeInsert:
            [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeDelete:
            [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeUpdate:
            [self.tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;

        case NSFetchedResultsChangeMove:
            [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
            [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
            break;
    }
}

- (void)controllerDidChangeContent:(NSFetchedResultsController *)controller
{
    if(self.suspendAutomaticTrackingOfChangesInManagedObjectContext) return;

    NSLog(@"Controller did change content");
    [self.tableView endUpdates];
}

【讨论】:

  • 这实际上为我的性能问题节省了很多痛苦。我在 UI 中遇到了严重的滞后,但我正在使用的数据量非常小,它似乎没有任何意义。事实证明它正在做你提到的事情,并且在视图不可见时停止跟踪会产生巨大的差异。感谢您发布您的解决方案,而不是让您的问题无人回答。巨大的帮助!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-02
相关资源
最近更新 更多