【问题标题】:Problem using NSRange: Index out of bounds使用 NSRange 的问题:索引超出范围
【发布时间】:2011-06-29 02:57:14
【问题描述】:

我正在尝试检测我的字符串中的网站 URL,然后做一些归属字符串的东西,比如加粗等。

我的正则表达式定义为:

static NSRegularExpression *websiteRegularExpression;
static inline NSRegularExpression * WebsiteRegularExpression() {
    if (!websiteRegularExpression) {
        websiteRegularExpression = [[NSRegularExpression alloc] initWithPattern:@"\b(https?|ftp|file)://[-A-Z0-9+&@#/%?=~_|!:,.;]*[A-Z0-9+&@#/%=~_|]" 
                                                                        options:NSRegularExpressionCaseInsensitive 
                                                                          error:nil];
    }

    return websiteRegularExpression;
}

这里是我列举的地方:

 -(void)setBodyText
    {
        __block NSRegularExpression *regexp = nil;    
        bodyLabel.delegate = self;
        [self.bodyLabel setText:@"http://www.google.com" afterInheritingLabelAttributesAndConfiguringWithBlock:^NSAttributedString *(NSMutableAttributedString *mutableAttributedString) {

            NSRange stringRange = NSMakeRange(0, [mutableAttributedString length]);

            regexp = WebsiteRegularExpression ();
            NSRange nameRange = [regexp rangeOfFirstMatchInString:[mutableAttributedString string] options:0 range:stringRange];
            UIFont *boldSystemFont = [UIFont boldSystemFontOfSize:18.0]; 
            CTFontRef boldFont = CTFontCreateWithName((CFStringRef)boldSystemFont.fontName, boldSystemFont.pointSize, NULL);
            if (boldFont) {
                [mutableAttributedString addAttribute:(NSString *)kCTFontAttributeName value:(id)boldFont range:nameRange];
                CFRelease(boldFont);
            }

            [mutableAttributedString replaceCharactersInRange:nameRange withString:[[[mutableAttributedString string] substringWithRange:nameRange] uppercaseString]];
            return mutableAttributedString;
        }];

        regexp = WebsiteRegularExpression();
        NSRange linkRange = [regexp rangeOfFirstMatchInString:self.bodyLabel.text options:0 range:NSMakeRange(0, [bodyLabel.text length])];
        [self.bodyLabel addLinkToURL:nil withRange:linkRange];
    }

我得到错误:

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSCFString substringWithRange:]: Range or index out of bounds'

我该如何解决?

【问题讨论】:

  • 你能发布你正在使用的正则表达式吗?具体来说什么是 mutableAttributedString。我的猜测是这条线出了点问题。 [mutableAttributedString replaceCharactersInRange:nameRange withString:[[[mutableAttributedString string] substringWithRange:nameRange] uppercaseString]];您可能希望通过确保每个步骤都符合您的预期来对其进行调试。
  • 我相信你是对的。我已经用正则表达式更新了我的代码。还是不知道怎么解决...

标签: iphone cocoa-touch nsstring nsrange


【解决方案1】:

在调用 substringWithRange 之前检查 nameRange 的内容。如果您的正则表达式不匹配,则 rangeOfFirstMatchInString 的返回值将是

{NSNotFound, 0}

NSNotFound 被定义为 NSIntegerMax,因此您可以想象为什么该值可能超出您的 mutableAttributedString 的范围。

评论更新

所以要检查substringWithRange的结果:

if (nameRange.location == NSNotFound)
    // didn't match the WebsiteRegularExpression() do something else

【讨论】:

  • 如何查看nameRange的内容?
  • @sheehan-alam 只需检查范围对象上的位置成员(请参阅更新)。
【解决方案2】:

您没有在任何地方检查您返回的任何范围是否具有 range.location = NSNotFound。您的一个匹配项即将出现空置,然后您正尝试将该范围用于其他事情。

【讨论】:

  • 我对 NSRange 还是很陌生,你能告诉我如何在我的代码中执行此检查的示例吗?
  • 由于 RedBlue 在回应中击败了我,我只是对他的回答投了赞成票。
猜你喜欢
  • 1970-01-01
  • 2021-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多