我有一個帶有UISearchBar的書籍應用程序,用戶輸入任何書名並在鍵入時獲取搜索結果(來自外部API調用)。使用帶有NSThread的單例同步數組
我在我的應用程序中使用了一個名爲retrieveArray的singleton變量,它存儲所有書籍。
@interface Shared : NSObject {
NSMutableArray *books;
}
@property (nonatomic, retain) NSMutableArray *books;
+ (id)sharedManager;
@end
這是訪問多個.m文件使用NSMutableArray * retrieveArray; ...在頭文件中
retrievedArray = [[Shared sharedManager] books];
我的問題是如何確保retrieveArray內的值在所有類中保持同步。
實際上,retrieveArray內的值是通過NSXMLParser(即通過外部Web服務API)添加的。有一個單獨的XMLParser.m文件,我在這裏完成所有的解析並填充數組。解析是在一個單獨的線程上完成的。
- (void) run: (id) param {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL: [self URL]];
[parser setDelegate: self];
[parser parse];
[parser release];
NSString *tmpURLStr = [[self URL]absoluteString];
NSRange range_srch_book = [tmpURLStr rangeOfString:@"v1/books"];
if (range_srch_book.location != NSNotFound)
[delegate performSelectorOnMainThread:@selector(parseDidComplete_srch_book) withObject:nil waitUntilDone:YES];
[pool release];
}
- (void) parseXMLFile: (NSURL *) url
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
[self setURL: url];
NSThread* myThread = [[NSThread alloc] initWithTarget:self
selector:@selector(run:)
object: nil];
[retrievedArray removeAllObjects];
[myThread start];
[pool release];
}
似乎有一些同步問題如果用戶鍵入速度非常快(這似乎是工作的罰款,如果慢的用戶類型)......因此,有2次,其中對象的內容顯示此共享數組項目;列表和詳細信息。 如果用戶輸入速度快,並在列表視圖中點擊A,他會在詳細視圖中顯示B ...這是主要問題。
我嘗試了所有我能想到的解決方案,但我仍然無法解決問題。
編輯同步問題示例: 在列表視圖中,如果顯示了3個項目,比如說Item1,Item2和Item3,並且用戶單擊Item2,則會在詳細視圖中顯示Item3(即,表示不正確詳細信息)
下面是在單擊列表視圖中的項目時被執行的代碼;
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
// Navigation logic -- create and push a new view controller
if(bookdetailCustom == nil)
bookdetailCustom = [[BookDetailCustom alloc] initWithNibName:@"BookDetailCustom" bundle:[NSBundle mainBundle]];
//aBook = [retrievedArray objectAtIndex:indexPath.row];
bookdetailCustom.selectedIndex = indexPath.row;
[self.navigationController pushViewController:bookdetailCustom animated:YES];
[bookdetailCustom release];
bookdetailCustom = nil;
}
這裏是searchTabkleView怎麼看起來像
- (void) searchTableView {
NSString *searchText = searchBar.text;
NSMutableArray *searchArray = [[NSMutableArray alloc] init];
for (int i=0;i<[retrievedArray count];i++)
{
Stock *aBookTemp = [retrievedArray objectAtIndex:i];
NSString *temp = [aBookTemp valueForKey:@"BookName"];
[searchArray addObject:temp];
}
for (NSString *sTemp in searchArray)
{
NSRange titleResultsRange = [sTemp rangeOfString:searchText options:NSCaseInsensitiveSearch];
if (titleResultsRange.length > 0)
[copyListOfItems addObject:sTemp];
}
[searchArray release];
searchArray = nil;
}
請建議一些適合的修復。
嘿,失戀......我很難在這裏解釋這個問題。但你似乎很瞭解這個問題非常準確...... 現在來解決問題,我想要走向你提出的第二種方法。 「 」另一種方法是解析器將結果累積到私有數組中,並且在發送List視圖以更新自身之前一次更新共享數組「 」您是否可以提供僞代碼你試圖說。我可以在我的應用程序中實現相同的功能,並查看它是否有效。 – testndtv 2011-02-28 18:53:01
但是,正如我所說的,因爲只有當用戶鍵入的速度非常快時纔會出現問題,這似乎與更新2個地方的陣列所花費的時間有關。再次感謝您對此的所有幫助。我已盡最大努力解決這個問題,沒有任何運氣,現在我真的很想解決這個問題。 – testndtv 2011-02-28 18:53:22
在您的NSXMLParserDelegate方法中,您必須將對象添加到retrieveArray中。 相反,在retrieveArray字段旁邊添加'temporaryArray'字段,在調用'[parser parse]之前將其設置爲新的NSMutableArray,將結果添加到delegate方法中的temporaryArray中,然後在[[parser parse]後面]返回調用'[retrieveArray replaceObjectsInRange:NSMakeRange(0,retrieveArray.count)withObjectsFromArray:temporaryArray]'。 – Anomie 2011-02-28 19:05:35