我正在制作一个搜索文本的应用程序(通过块方法枚举整个文本)。搜索控制器类应该将结果编译成一个数组,然后通过委托方法返回。
我知道搜索逻辑正在运行,因为在我添加委托方法之前我得到了结果,而我的resultsCount整数仍然记录了预期的结果数。我改变的是在队列中调用此方法,并按如下方式将其分派回主队列:
searchQueue = dispatch_queue_create("searchQueue", NULL);
dispatch_async(searchQueue, ^{
dispatch_async(dispatch_get_main_queue(), ^ {
[controller performSearchWithString:searchText andTexts:[self textsToSearch]];
});
因为我这样做了,我的实际数组没有拾取这些对象的任何(或者它立即转储它们?) - 它总是记录“null”。我不知道为什么。将数组声明为__block对象不会更改它,也不会将其创建为类的属性。这是我的方法代码:
-(void)performSearchWithString:(NSString *)searchString andTexts:(NSSet *)texts
{
NSMutableArray *pendingResults = nil;
__block int resultsCount = 0;
NSError *error = nil;
for (id book in texts) {
if ([book isEqual:kBook1]){
NSURL *url = [[NSBundle mainBundle] URLForResource:@"neiJing" withExtension:@"txt"];
NSString *text = [NSString stringWithContentsOfURL:url encoding:NSStringEncodingConversionAllowLossy error:&error];
[text enumerateSubstringsInRange:NSMakeRange(0, [text length])
options:NSStringEnumerationByWords
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
//NSRange found = [substring rangeOfString:text];
if ([searchString caseInsensitiveCompare:substring] == NSOrderedSame) {
SearchResult *result = [[SearchResult alloc] init];
result.title = @"neiJing";
result.author = @"Author";
//result.excerpt = substring; // Add logic to configure excerpt range
result.range = NSMakeRange(substringRange.location-500, substringRange.length + 500);
result.excerpt = [NSString stringWithFormat:@"...%@...",[text substringWithRange:result.range]];
[pendingResults addObject:result];
NSLog(@"%@", pendingResults);
resultsCount++;
}
}];
}
if (error == nil) {
[self.delegate SearchControllerDidReturnResults:[NSArray arrayWithArray:pendingResults]];
}
非常感谢任何帮助。我仍然在努力理解积木,没有直接“C”背景,但我想我已经掌握了变量范围的影响。似乎我仍然缺少一个关键概念。
答案 0 :(得分:4)
在我看来,您遇到了Objective-C的一个特点,即您可以将变量设置为nil
并仍然向其发送消息。
程序将默默地继续运行,不会出现任何错误消息,警告或其他可能未初始化变量的迹象。
因此,当您设置pendingResults = nil
然后再调用
[pendingResults addObject:result];
效果将是addObject:
消息被发送到nil
,绝对没有结果,甚至没有控制台消息。
我的猜测是,如果您将pendingResults
的声明更改为:
NSMutableArray *pendingResults = [NSMutableArray array];
事情将开始发生。也许不是正确的事情(这是很多代码,许多事情仍然可能出错)但你会在你的数组中得到某些东西。
虽然nil
的这种(非)处理可能看起来像一个“特征”,使得查找错误更加困难(并且确实如此),但这也意味着在许多情况下Objective-C代码很多比“竞争”更清洁。为了比较,看看Java,它左右抛出可怕的NullPointerException
,导致许多人乱丢代码,测试指针是非空的。
因此,一旦你掌握了Objective-C的这个特殊方面,它最终成为你在调试器中检查的第一件事(你做使用调试器,对吗?)< / p>