2

我正在尝试实现一个专门的typed记录器,它将字典作为输入并从中创建值字符串。

一个这样的字典样本可能是:

CGSize size = {300, 200} ;
CGAffineTransform t = ::CGAffineTransformIdentity ;

[self logit: @{
    @"columns": @{
        @"value": @3
    ,   @"type": @"NSNumber"
    }
,   @"size": @{
        @"value": [NSValue valueWithCGSize(size)]
    ,   @"type": @"CGSize"
    }
,   @"transform": @{
        @"value": [NSValue valueWithCGAffineTransform(t)]
    ,   @"type":    @"CGAffineTransform"
    }
}] ;

问题是:如何以通用方式检索这些值?

我显然可以写

    for (NSString * key in dict) {
        NSDictionary * params = dict[key] ;

        if ([params[@"type"] isEqualToString: @"CGRect"]) {
            CGRect r = [params[@"value"] CGRectValue] ;
            NSString * s = ::NSStringFromCGRect(r) ;
            ::NSLog(s) ;
        } else if ([params[@"type"] isEqualToString: @"NSNumber"]) {
            ::NSLog(@"%.3f", [params[@"value"] floatValue]) ;
        } else if ([params[@"type"] isEqualToString: @"CGAffineTransform"]) {
            CGAffineTransform t = [params[@"value"] CGAffineTransformValue]
            NSString * s = ::NSStringFromCGAffineTransform(t) ;
            ::NSLog(s) ;
        }
        ...
    }

但我宁愿写一个更“通用”的解决方案。类似的东西:

SEL valueSelector = ::NSSelectorFromString([NSString stringWithFormat:@"%@Value", params[@"type"]) ;
NSString * rawCFunctionName = [NSString stringWithFormat:@"NSStringFrom%@", params[@"type"]] ;

所以现在我有一个选择器和一个 C 函数的名称。

  1. 如何从字符串转到我可以实际调用的 C 函数?

  2. 使用上面的选择器尚不清楚,因为它的返回类型可能会有所不同,id例如:在NSNumber *“普通 C 对象”的情况下CGRect,例如在CGSize等的情况下......

有什么建议吗?

4

1 回答 1

2
  1. 你不能;请参阅“在 C 中调用以字符串变量命名的函数”。

  2. 是的,您必须在编译时知道返回类型。

然而,一切都不会丢失:您尝试做的事情实际上可以以相当平凡的方式完成。NSValue有一个非常好的特性,它的description方法给出的输出非常类似于NSStringFrom...()它存储的类型的适当函数(它可能在引擎盖下使用它们)。例如:

NSLog(@"%@", [NSValue valueWithCGAffineTransform:CGAffineTransformMake(10, 10, 10, 10, 10, 10)]);
NSLog(@"%@", [NSValue valueWithCGSize:CGSizeMake(10, 10)]);

产量:

2013-08-11 03:06:43.053 PrintingNSValue[51538:11303] CGAffineTransform: {{10, 10, 10, 10}, {10, 10}}
2013-08-11 03:06:43.055 PrintingNSValue[51538:11303 ] NSS 大小:{10, 10}

NSNumber同样会很好地表示它的价值作为它的描述。

所以你所要做的就是这样的:

for( NSString * key in theDictionary ){
    NSLog(@"%@: %@", key, theDictionary[key][@"value"]);
}
于 2013-08-11T03:19:42.660 回答