阻止将对象添加到数组...无法使其工作

时间:2013-04-01 18:01:59

标签: ios objective-c xcode objective-c-blocks

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

我知道搜索逻辑正在运行,因为在我添加委托方法之前我得到了结果,而我的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”背景,但我想我已经掌握了变量范围的影响。似乎我仍然缺少一个关键概念。

1 个答案:

答案 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>