【问题标题】:Concatenating macro name with NSString将宏名称与 NSString 连接起来
【发布时间】:2014-07-30 14:14:35
【问题描述】:

我有几个宏定义如下:

#define text @"play"
#define text_s @"stop"
#define text_f @"forward"
#define text_r @"rewind"
#define text_m @"mute"

我有一个NSArray 填充字符串,例如@""@"_s"@"_f"@"_r"@"_m"

因此,在运行时,我想将此数组中的一个字符串与宏名称连接起来,例如,@"text"

换句话说,我想通过将它(即“文本”)与@""@"_s"@"_f"@"_r"@"_m" 连接来根据条件获取相应的宏并得到对应的宏。

到目前为止我已经尝试过使用:

label.text = [NSString stringWithFormat:@"%@%@", text, [myArray objectAtIndex:<INDEX>]];

但这只会将字符串(例如,如果它是@“stop”)与宏文本连接起来 它会变成“playstop”。

我想要归档的是能够连接字符串(即前缀)并形成一个宏名称并相应地使用它。

例如:如果使用@"_s",我会得到宏text_s,如果使用@"_f",那么将使用宏text_f

我该如何存档?如何在运行时将宏名称与字符串(即@"_s")连接起来?

【问题讨论】:

  • 你不知道宏是如何工作的。这不是宏的工作方式。请了解宏是如何工作的。它们不会出现在您的编译代码中。
  • 当你定义一个宏,比如#define text @"play",编译器用@"play"替换每个对text宏的引用。您无法在运行时访问宏。
  • 为什么真的需要使用宏?
  • @Unhelig 宏在运行时不存在,因此您无法调用它。您可以定义一个宏来返回另一个宏的名称 (#define MACRO_NAME(x) #x),但您仍然不能在运行时调用它,因为在编译时宏被编译器替换。例如,MACRO_NAME(text) 由编译器转换为 "text"。请记住,宏不是运行时函数。
  • 宏是用于compiler-time的,你的代码是用于runtime的。它们没有共同的集合。

标签: ios objective-c macros


【解决方案1】:

您可以创建一个宏,它接受一个变量并根据输入分配您的字符串。 (这也可以是一个全局函数,但既然你坚持使用宏,这里是一个选项:

#define getText(a) \
    [a isEqualToString:@""] ? @"play" : \
    [a isEqualToString:@"_s"] ? @"stop" : \
    [a isEqualToString:@"_f"] ? @"forward" : \
    [a isEqualToString:@"_r"] ? @"rewind" : \
    [a isEqualToString:@"_m"] ? @"mute" : \
    @""

你可以这样称呼它:

NSString *string = getText(@"_s");
//string is now @"stop"

它会有点慢,但它会完成工作。这会很慢,因为如果您希望宏静音,它必须首先检查您发送的字符串与其他 4 个字符串。每秒调用一千次会很慢,但如果你每分钟只需要一次,那就没关系了。同样,对于这种类型的行为有更好的选择,但如果您需要这个解决方案,它会起作用。

需要说明的是,这个宏不能在编译时使用,只能在运行时使用。因此,如果您需要可以在 .h 文件中使用的东西,这将不会。

更好的解决方案是将这些字符串添加到数组中,而不是添加@"_m", @"_r" 等。创建数组时,只需用最终数据填充它,而不是永远不会更改的临时数据集。我对您的应用程序了解不够,它需要为您提供满足您需求的最佳解决方案。您只需要找到有效且安全的方法即可。

根据您的信息更新:

最好的情况是将所有宏重写为更有用的信息,但由于这是针对学校的,性能并不是最重要的...

#define text @"play"
#define text_s @"stop"
#define text_f @"forward"
#define text_r @"rewind"
#define text_m @"mute"
#define getText(a) \
    [a isEqualToString:@""] ? text : \
    [a isEqualToString:@"_s"] ? text_s : \
    [a isEqualToString:@"_f"] ? text_f : \
    [a isEqualToString:@"_r"] ? text_r : \
    [a isEqualToString:@"_m"] ? text_m : \
    @""

或:

#define text @"play"
#define text_s @"stop"
#define text_f @"forward"
#define text_r @"rewind"
#define text_m @"mute"

yourClassDictionary = @{ @"" : text,
                    @"_s": text_s,
                    @"_f": text_f,
                    @"_r": text_r,
                    @"_m": text_m };

字典会是最快的。两者都适合您的情况。

【讨论】:

  • @Unheilig 我用原因和一个选项更新了我的答案。我不像你那样了解你的应用程序,所以我不能说什么最有效。只要找到有效、干净、安全的东西,你就应该很好。
  • 听起来您将不得不创建多个字典来适应这种情况。或者你可以更新上面的宏。我会在一秒钟内发布更新。
  • 谢谢,我试试这个。
【解决方案2】:

如果您实际上不必使用宏,我会做这样的事情......

NSDictionary *text = @{ @"" : @"play",
                        @"_s": @"stop",
                        @"_f": @"forward",
                        @"_r": @"rewind",
                        @"_m": @"mute" };

然后得到这样的值:

text[suffix];

其中后缀是@""@"_s" 等之一。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-29
    • 2022-12-11
    相关资源
    最近更新 更多