这是一个健全的Objective-C模块实现吗?

这是一个健全的Objective-C模块实现吗?,objective-c,objective-c-blocks,objective-c-category,Objective C,Objective C Blocks,Objective C Category,我想要一个NSRegularExpression的–StringByReplacingMatchesInstalling:options:range:withTemplate:方法的变体,该方法采用块而不是模板。块的返回值将用作替换值。正如您所想象的,这比模板更灵活。有点像在Perl正则表达式中使用/e修饰符 所以我写了一个类别来添加这个方法。这就是我想到的: @implementation NSRegularExpression (Block) - (NSString *)stringByR

我想要一个NSRegularExpression的
–StringByReplacingMatchesInstalling:options:range:withTemplate:
方法的变体,该方法采用块而不是模板。块的返回值将用作替换值。正如您所想象的,这比模板更灵活。有点像在Perl正则表达式中使用
/e
修饰符

所以我写了一个类别来添加这个方法。这就是我想到的:

@implementation NSRegularExpression (Block)

- (NSString *)stringByReplacingMatchesInString:(NSString *)string
                                       options:(NSMatchingOptions)options
                                         range:(NSRange)range
                                    usingBlock:(NSString* (^)(NSTextCheckingResult *result))block
{
    NSMutableString *ret = [NSMutableString string];
    NSUInteger pos = 0;

    for (NSTextCheckingResult *res in [self matchesInString:string options:options range:range]) {
        if (res.range.location > pos) {
            [ret appendString:[string substringWithRange:NSMakeRange(pos, res.range.location - pos)]];
        }
        pos = res.range.location + res.range.length;
        [ret appendString:block(res)];
    }
    if (string.length > pos) {
        [ret appendString:[string substringFromIndex:pos]];
    }
    return ret;
}

@end
这是我第一次尝试在Objective C中使用积木。感觉有点奇怪,但似乎效果不错。不过,我有几个问题要问:

  • 这似乎是实现这种方法的明智方法吗
  • 是否有某种方法可以使用
    -EnumerateMatchesInstalling:options:range:usingBlock:
    
    ?我尝试了,但无法从块内分配到
    pos
    。但是如果有一种方法可以让它工作,那么传递NSMatchingFlags和BOOL并以与该方法相同的方式处理它们会很酷。你有能力吗

  • 更新

    多亏了Dave DeLong的回答,我得到了一个使用块的新版本:

    @implementation NSRegularExpression (Block)
    
    - (NSString *)stringByReplacingMatchesInString:(NSString *)string
                                           options:(NSMatchingOptions)options
                                             range:(NSRange)range
                                        usingBlock:(NSString * (^)(NSTextCheckingResult *result, NSMatchingFlags flags, BOOL *stop))block
    {
        NSMutableString *ret = [NSMutableString string];
        __block NSUInteger pos = 0;
    
        [self enumerateMatchesInString:string options:options range:range usingBlock:^(NSTextCheckingResult *match, NSMatchingFlags flags, BOOL *stop)
        {
            if (match.range.location > pos) {
                [ret appendString:[string substringWithRange:NSMakeRange(pos, match.range.location - pos)]];
            }
            pos = match.range.location + match.range.length;
            [ret appendString:block(match, flags, stop)];
        }];
        if (string.length > pos) {
            [ret appendString:[string substringFromIndex:pos]];
        }
        return [NSString stringWithString:ret];
    }
    
    @end
    

    很好,谢谢

    能够从块内分配到
    pos
    ,就如同从以下位置更改声明一样简单:

    NSUInteger pos = 0;
    
    致:


    有关
    \u块的更多信息
    关键字:

    完全合理和“Dave说了什么”。)太棒了,谢谢!我将使用一个块用新版本更新这个问题。这非常方便。非常感谢。
    __block NSUInteger pos = 0;