У меня есть приложение для книг с UISearchBar, где пользователь вводит любое название книги и по мере ввода получает результаты поиска (из вызова внешнего API) ниже.
Я использую в своем приложении одноэлементную переменную retrievedArray, в которой хранятся все книги.
@interface Shared : NSObject {
NSMutableArray *books;
}
@property (nonatomic, retain) NSMutableArray *books;
+ (id)sharedManager;
@end
Доступ к ней осуществляется в нескольких файлах .m с помощью NSMutableArray * retrievedArray; ... в файле заголовка
retrievedArray = [[Shared sharedManager] books];
Мой вопрос заключается в том, как обеспечить синхронизацию значений внутри retrievedArray во всех классах.
На самом деле значения внутри retrievedArray добавляются через NSXMLParser (то есть через 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 представления, в которых отображается содержимое объекта в этом элементе общего массива; Список и детали. где я занимаюсь парсингом и заполняю массив. Анализ выполняется в отдельном потоке.
- (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 представления, в которых отображается содержимое объекта в этом элементе общего массива; Список и детали. где я занимаюсь парсингом и заполняю массив. Анализ выполняется в отдельном потоке.
- (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;
}
Пожалуйста, предложите несколько подходящих исправлений.