gpt4 book ai didi

iOS:如何调试 UI 延迟 [iPad2 双核]

转载 作者:可可西里 更新时间:2023-11-01 04:44:41 34 4
gpt4 key购买 nike

在我的应用程序中,我必须处理来自网络的大量数据并将其解析为优化的本地格式,然后将它们保存到数据库或将它们发送到 UI(如果有任何 UI 正在等待该数据)。

我知道在主线程中进行繁重的解析工作是愚蠢的,因为它会阻塞主线程并使 UI 交互非常不稳定。

所以这是我试图确保 UI 线程空闲的方法:

  • 全局优化以删除非常慢的代码,无论它在哪个线程中。
  • 降低所有线程的优先级,即

    NSOperation.threadPriority=0.1;
    NSThread.threadPriority=0.1;
    dispatch_async(dispatch_get_global_queue(PRIORITY_LOW));

经过这两个步骤后,当一些繁重的工作在后台线程中完成时,UI 变得更加流畅,但仍然非常跳跃

错误看起来是这样的:当我非常流畅地滚动表格时,突然表格卡住了大约 0.1 秒,然后像往常一样平滑地继续滚动。在卡住期间,我可以看到 Instruments 中的 CPU 爆发。但是在单独的线程 View 中,我可以看到主线程运行良好,几乎没有 CPU 消耗。

  1. 那么为什么 UI 表仍然卡住?
  2. 为什么后台线程设置如此低的线程优先级仍然占用如此多的 CPU 周期?
  3. 你们如何确保 UI 始终响应?
  4. 是否有任何有用的工具可以突出显示导致 UI 卡住的地方?

最佳答案

一个好的解决方案是使用 Grand Central Dispatch (GCD) 和 Objective-C blocks结合本地缓存。当您的表格单元格加载时,您应该尽快从 tableView:cellForRowAtIndexPath: 返回,表格单元格已设置好任何本地保存的数据。需要下载数据或进行任何繁重处理的单元格的任何部分都应该有一个占位符(例如事件指示器)。繁重的处理或下载将发生在另一个线程上,如下所示:

// ...This code is at the end of tableView:cellForRowAtIndexPath: where cell
// is already set up and you should have access to your cache and your data
// manager object that will do the processing or downloading for you.

// Show the placeholder (it will hide when real data is set)
cell.placeholder.hidden = NO;
// Check if item is local
MyDataItem* item = [myCache objectForKey:itemKey];
if(item != nil)
{
// Item is available locally, set up the cell now
cell.someImageView.image = item.image;
cell.someLabel.text = item.text;
cell.placeholder.hidden = YES;
}
else
{
// Item is not in cache, go and get it ready
[myDataManager goAndGet:itemKey completion:^(MyDataItem* theItem)
{
// Put the item in the cache
[myCache setObject:theItem forKey:itemKey];
// This block will be executed later and the cell may have been reused
// by then, so we need to ask the table view directly for the cell.
// This returns nil if cell is not currently visible.
MyTableCell* theCell = (MyTableCell*)[tableView cellForRowAtIndexPath:indexPath];
// Set up the table cell
if(theCell != nil)
{
myCell.someImageView.image = theItem.image;
myCell.someLabel.text = theItem.text;
myCell.placeholder.hidden = YES;
}
}];
}
return cell;

正如您从上面的代码中看到的,即使需要进行一些繁重的处理,单元格也会很快返回。这使 UI 保持良好和响应,而不会导致在 TableView 上滚动时出现任何延迟。数据管理器将使用 GCD 来执行处理,如下所示:

- (void)goAndGet:(NSString*)itemKey completion:(void (^)(MyDataItem* theItem))completionBlock
{
// Note: this uses DISPATCH_QUEUE_PRIORITY_DEFAULT - but you might want to use
// a different queue, probably one you created yourself for these tasks.
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^
{
// Do heavy processing or downloading here
MyDataItem* item = [heavyProcessor doProcessingForItem:itemKey];

// The completion block must happen on the main queue
dispatch_async(dispatch_get_main_queue(), ^
{
// Call the completion block
completionBlock(item);
});
});
}

请注意,以上所有代码均假设您使用的是 ARC :)

关于iOS:如何调试 UI 延迟 [iPad2 双核],我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9633206/

34 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com