【问题标题】:Blocks adding objects to an array...can't get it to work [duplicate]阻止将对象添加到数组中......无法使其工作[重复]
【发布时间】:2013-03-22 20:17:00
【问题描述】:

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

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

【问题讨论】:

  • 看起来pendingResults 从未分配过?
  • 我很确定这不是使用dispatch_async 的正确方法。在第二次调用 dispatch_async 之前,您应该使用您的 searchQueue 线程执行搜索,然后重新输入 dispatch_get_main_queue() 以使用结果更新 UI。

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


【解决方案1】:

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

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

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

[pendingResults addObject:result];

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

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

NSMutableArray *pendingResults = [NSMutableArray array];

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

虽然nil 的这种(非)处理可能看起来像是一个“功能”,使查找错误变得更加困难(确实如此),但这也意味着在许多情况下,Objective-C 代码比比赛”。作为比较,看看 Java,它会左右抛出其可怕的NullPointerException,导致许多人在他们的代码中乱扔指针,测试指针是否为非空。

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

【讨论】:

  • 非常感谢!我很尴尬犯了这样一个菜鸟的错误——一旦你指出它就非常明显了。该数组从未正确初始化(我的模糊的 6AM 头决定在每次调用该方法时将其设置为“nil”,认为我需要清除它)。非常非常感谢!
猜你喜欢
  • 2011-02-17
  • 2013-01-03
  • 2022-01-05
  • 2020-12-09
  • 1970-01-01
  • 2020-11-21
相关资源
最近更新 更多