我有一个带有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