Использование синхронизированного массива Singleton с NSThread

У меня есть приложение для книг с 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;
}

Пожалуйста, предложите несколько подходящих исправлений.

5
задан testndtv 7 March 2011 в 17:14
поделиться