Oma*_*arj 10 iphone objective-c grand-central-dispatch ios ios6
我正在尝试加速我的应用搜索,当有大量数据时它会滞后.
所以我试图分裂搜索谓词的UI使用dispatch_async不会dispatch_sync造成任何不同,如果我使用它.
问题是当我使用时dispatch_async,应用程序崩溃有时是因为[__NSArrayI objectAtIndex:]: index "17" beyond bounds.
我现在发生这种情况是因为我们说第一个仍然工作并重新加载tableView并继续搜索将改变数组大小取决于结果所以在这种情况下"CRASH":(
这是我的代码:
dispatch_async(myQueue, ^{
searchArray = [PublicMeathods searchInArray:searchText array:allData];
} );
if(currentViewStyle==listViewStyle){
[mytable reloadData];
}
Run Code Online (Sandbox Code Playgroud)
我试过这个:
dispatch_async(myQueue, ^{
NSArray *tmpArray = [PublicMeathods searchInArray:searchText array:allData];
dispatch_sync(dispatch_get_main_queue(), ^{
searchArray = tmpArray;
[mytable reloadData];
});
});
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,滞后仍然存在.
更新-1-:
努力工作后搜索Predicate只用了2ms :)但是当用户搜索时键盘仍然滞后,所以我得到的结果之后我唯一能做的就是重新加载表"改变用户界面"这个我认为让它滞后,
所以我搜索分裂这两个操作"在键盘上打字和刷新UI".
更新-2-:
@matehat /sf/answers/1181593031/
和
@TomSwift /sf/answers/1180623461/
答案像魅力一样工作:)
如果searchArray是用作表视图数据源的数组,则只能在主线程上访问和修改此数组.
因此,在后台线程上,您应首先过滤到单独的临时数组.然后将临时数组分配给searchArray主线程:
dispatch_async(myQueue, ^{
NSArray *tmpArray = [PublicMeathods searchInArray:searchText array:allData];
dispatch_sync(dispatch_get_main_queue(), ^{
searchArray = tmpArray;
[mytable reloadData];
});
});
Run Code Online (Sandbox Code Playgroud)
更新:使用临时数组应解决崩溃问题,使用后台线程有助于在搜索过程中保持UI响应.但正如在讨论中发现的那样,搜索速度缓慢的一个主要原因可能是复杂的搜索逻辑.
它可能有助于存储额外的"标准化"数据(例如,所有数据都转换为小写,电话号码转换为标准格式等等),以便可以通过更快的不区分大小写的比较来完成实际搜索.
一种解决方案可能是自愿在搜索之间引入延迟,以便让用户键入并异步执行搜索。就是这样:
首先确保您的队列是这样创建的:
dispatch_queue_t myQueue = dispatch_queue_create("com.queue.my", DISPATCH_QUEUE_CONCURRENT);
Run Code Online (Sandbox Code Playgroud)
在您的类中定义此 ivar(并FALSE在初始化时将其设置为):
BOOL _scheduledSearch;
Run Code Online (Sandbox Code Playgroud)
将此宏写在文件顶部(或任何地方,只需确保其可见)
#define SEARCH_DELAY_IN_MS 100
Run Code Online (Sandbox Code Playgroud)
并且调用此方法而不是第二个片段:
[self scheduleSearch];
Run Code Online (Sandbox Code Playgroud)
其实现是:
- (void) scheduleSearch {
if (_scheduledSearch) return;
_scheduledSearch = YES;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t)((double)SEARCH_DELAY_IN_MS * NSEC_PER_MSEC));
dispatch_after(popTime, myQueue, ^(void){
_scheduledSearch = NO;
NSString *searchText = [self textToSearchFor];
NSArray *tmpArray = [PublicMeathods searchInArray:searchText array:allData];
dispatch_async(dispatch_get_main_queue(), ^{
searchArray = tmpArray;
[mytable reloadData];
});
if (![[self textToSearchFor] isEqualToString:searchText])
[self scheduleSearch];
});
}
Run Code Online (Sandbox Code Playgroud)
[self textToSearchFor]是您应该从中获取实际搜索文本的地方。
它的作用如下:
_scheduledSearch为TRUE并告诉 GCD 在 100 毫秒内安排搜索_scheduledSearchivar 重置为FALSE,以便处理下一个请求。您可以使用不同的值来SEARCH_DELAY_IN_MS使其满足您的需求。该解决方案应该将键盘事件与搜索生成的工作负载完全解耦。
| 归档时间: |
|
| 查看次数: |
3083 次 |
| 最近记录: |