C预处理器宏将字符串转换为令牌?

时间:2013-02-12 11:00:09

标签: objective-c gcc llvm c-preprocessor

我正在尝试为LLVM编写一个C预处理器宏,其使用方式如下:

vc(@"Browser")

并扩展为:

[[BrowserViewController alloc] initWithNibName:@"BrowserViewController" bundle:nil]

我能想到的最好的是:

vc(Browser)

实现为:

#define vc(xibName) [[xibName ## ViewController alloc] initWithNibName:[NSString stringWithFormat:@"%@ViewController", @#xibName] bundle:nil]

然而对于用户而言,这似乎令人困惑,因为Browser本身(在字符串文字之外)看起来像一个标记。 @"Browser"会使意图更清晰,而无需用户阅读宏。

修改

这背后的动机乍一看似乎很傻,但我在iPhone,iPad和OS X的应用程序上工作,每个人都有自己的方式来实例化一个视图控制器,其视图在Interface Builder中布局。

ipad公司:

[[UIStoryboard storyboardWithName:@"StoryboardPad" bundle:nil] instantiateViewControllerWithIdentifier:@"Browser"];

iPhone:

[[UIStoryboard storyboardWithName:@"StoryboardPhone" bundle:nil] instantiateViewControllerWithIdentifier:@"Browser"];

OS X:

[[BrowserViewController alloc] initWithNibName:@"BrowserViewController" bundle:nil]

由于它都是Objective-C,我的一些控制器可以跨平台重用,而且每次我想要一个视图控制器时,我都不喜欢用条件编译语句来丢弃我的代码。此外,当您在一周中的不同日子在不同的平台上工作时,有助于您知道您可以致电vc(@"Browser")并获得您所期望的,无论是iPad还是iPad,iPhone或MAC。这只是一个约定与配置的问题。

2 个答案:

答案 0 :(得分:2)

如果你只是打电话

[[BrowserViewController alloc] init];

然后UIViewController将按以下方式搜索具有适当名称的xib

  
      
  1. 如果视图控制器类名以单词“Controller”结尾,就像在MyViewController中一样,它会查找名称与类名匹配的nib文件,而不是像“MyView.nib”那样的单词“Controller”。

  2.   
  3. 它查找名称与视图控制器类名称匹配的nib文件。例如,如果类名是MyViewController,它会查找MyViewController.nib文件。

  4.   

上面一行代码应该足够短,不能证明宏的合理性;)

答案 1 :(得分:0)

原来一个函数是实现这个的方法:

id InstantiateViewControllerWithXib(NSString *xibName) {
    NSString *className = [xibName stringByAppendingString:@"ViewController"];
    return [[NSClassFromString(className) alloc] initWithNibName:className bundle:nil];
}

要严格回答问题,您可以定义所需的宏:

#define vc(xibName) InstantiateViewControllerWithXib(xibName)