[問題] 在Obj-C 下做搜尋字串的功能
這陣子開發一個英漢字典的功能時 發現一些問題
主要是利用 UISearchDisplayController 來呈現搜尋字典的UI
在search時 並不是利用predicate來重新fetch
而是在fetchedObjects中找出最接近符合字串的index
並利用table view的-scrollToRowAtIndexPath:atScrollPosition:animated:
跳到搜尋到最接近的cell
這樣User還是能在全部的字典內上下捲動瀏覽字庫
搜尋流程總共含下面幾個步驟:
1. 在UISearchBarDelegate的方法來觸發搜尋字典功能
- (void)searchBar:(UISearchBar *)searchBar
textDidChange:(NSString *)searchText{
// 在有輸入字串的情況下進行非同步搜尋
if (![searchText isEqualToString:@""]) {
[self asyncSearchText:searchText];
}
}
2. 進行非同步搜尋字串
- (void)asyncSearchText:(NSString*)text{
[self.operationQueue addOperationWithBlock:^{
[self searchText:text];
}
}
- (void)searchText:(NSString*)text{
// 利用NSArray的-indexOfObjectPassingTest:
// 來對之前fetch出來的vocabularies進行字串比對搜尋
// 這邊是簡化的code,事實上我將字典依單字的字母開頭分成A-Z 26個資料庫
// 在search時,會依照字首來決定使用哪個fetchedObjects做進一步搜尋
// **fetchedObjects已經經過NSSortDescriptor的caseInsensitiveCompare:排序
NSArray *vocabularies = self.fetchedResultsController.fetchedObjects;
// Problem 1: 請見後面討論
NSInteger foundRow = [vocabularies indexOfObjectPassingTest:
^BOOL(id obj, NSUInteger idx, BOOL *stop) {
// 將fetchedObjects中每個Vocabulary物件進行比對
Vocabulary *vocabulary = obj;
NSComparisonResult comparisonResult = [vocabulary.word
compare:text options:NSCaseInsensitiveSearch];
if (comparisonResult != NSOrderedAscending) {
*stop = YES;
return YES;
}
return NO;
}
// 獲得indexPath
NSIndexPath *foundIndexPath = [self foundIndexPathForFoundRow:foundRow
forText:text];
// 通知更新searchResultsTableView
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
[self searchedText:text foundAtIndexPath:foundIndexPath];
}];
}
3. 更新searchResultsTableView
- (void)searchedText:(NSString*)text foundAtIndexPath:(NSIndexPath*)indexPath{
// Problem 2: 請見後面討論
[self.searchDisplayController.searchResultsTableView
scrollToRowAtIndexPath:indexPath
atScrollPosition:UITableViewScrollPositionTop
animated:YES];
}
以上是簡化的一個流程 以上程式碼在搜尋時是可以work
但是當鍵盤輸入過於快速時(大約超過每秒2個字母) 會發生以下問題:
Problem 1:
當輸入過於快速時 發現到async的operation會一直卡在isExecuting的狀態
發現是卡在NSArray的-indexOfObjectPassingTest:裡面出不來 不知道為什麼
朋友說試著改用suffix tree來做搜尋 (不過我還沒研究...)
目前字串搜尋速度效率我可以接受 只不過不知道為什麼會發生這種情況... Orz
Problem 2:
當輸入過於快速時 會發生UI整個卡住不能動的情況
把-scrollToRowAtIndexPath:atScrollPosition:animate:給comment out就不會卡住
原本推測是前一個scroll的animation還沒結束就實行下一個scroll造成
但是利用mainQueue 進行 serial operation 也是一樣會卡(就是捲完一個再捲下一個)
我看其他字典軟體的App都可以做出來我想要的結果 可是我遇到這些問題不知道該怎麼辦
希望大家可以給一點意見..
--
※ 發信站: 批踢踢實業坊(ptt.cc)
◆ From: 111.80.236.201
推
09/23 00:59, , 1F
09/23 00:59, 1F
→
09/23 22:40, , 2F
09/23 22:40, 2F
討論串 (同標題文章)
以下文章回應了本文:
完整討論串 (本文為第 1 之 2 篇):
MacDev 近期熱門文章
PTT數位生活區 即時熱門文章