0

我正在制作一个搜索文本的应用程序(通过块方法枚举整个文本)。搜索控制器类应该将结果编译成一个数组,然后通过委托方法返回。

我知道搜索逻辑正在工作,因为在添加委托方法之前,我正在获取结果,并且我的 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”的背景,但我认为我掌握了变量范围是如何受到影响的。似乎我仍然缺少一个关键概念。

4

1 回答 1

4

在我看来,您似乎遇到了 Objective-C 的特性之一,即您可以保留一个变量集nil并仍然向它发送消息。

程序将静默继续,没有任何错误消息、警告或其他变量可能未初始化的迹象。

因此,当您设置pendingResults = nil然后稍后调用

[pendingResults addObject:result];

结果将是消息addObject:被发送到nil,绝对没有结果,甚至没有控制台消息。

我的猜测是,如果您将声明更改pendingResults为:

NSMutableArray *pendingResults = [NSMutableArray array];

事情将开始发生。也许不是正确的事情(它有很多代码,很多事情仍然可能出错)但你会在你的数组中得到一些东西。

虽然这种(非)处理nil可能看起来像一个“特性”,它使查找错误变得更加困难(而且确实如此),但这也意味着在许多情况下,Objective-C 代码比“竞争”要干净得多。作为比较,看看 Java,它NullPointerException左右摇摆不定,导致许多人在代码中乱扔指针,测试指针是否为非空。

因此,一旦您掌握了 Objective-C 的这一特殊方面,它最终会成为您在调试器中检查的第一件事(并且您确实使用了调试器,对吗?)

于 2013-04-01T18:15:02.220 回答