代码之家  ›  专栏  ›  技术社区  ›  Elise van Looij

在objective-c协议中定义字符串常量的最佳方法是什么?

  •  11
  • Elise van Looij  · 技术社区  · 16 年前

    我定义了一个所有插件都必须实现的协议。我还希望插件都使用某些字符串,比如MyPluginErrorDomain。对于整数,这在枚举中很容易实现,但我不知道如何对字符串执行同样的操作。通常,在类中我会定义

    extern NSString * const MyPluginErrorDomain;
    

    在.h文件和.m文件中:

    NSString * const MyPluginErrorDomain = @"MyPluginErrorDomain";
    

    然后我试着

    #define MYPLUGIN_ERROR_DOMAIN @"MyPluginErrorDomain"
    

    但是插件中的实现类似乎看不到#define。谁知道一个好的解决办法?

    4 回复  |  直到 16 年前
        1
  •  10
  •   philsquared    16 年前

    您可以在协议的头中声明它们(但在协议接口本身之外),然后在协议的实现文件中定义它们(显然它没有 @implementation 部分-只是你的 NSString 定义)。

    或者有一个单独的.h/.m对,仅用于字符串常量(协议头可以导入字符串常量头)。

        2
  •  9
  •   stefanB    16 年前

    extern NSString * const MyPluginErrorDomain;
    

    但将此部分放入一个单独的.m文件中,该文件将包含在您的框架中:

    NSString * const MyPluginErrorDomain = @"MyPluginErrorDomain";
    

    因此,插件仍然可以实现接口,但在编译时,它们会链接或编译到另一个.m文件中,因此它们会看到 MyPluginErrorDomain

        3
  •  3
  •   anon anon    16 年前

    在C++中,我会在这样的标题中声明它们:

    const char * const MYPLUGIN_ERROR_DOMAIN = "MyPluginErrorDomain";
    const char * const MYPLUGIN_FOO_DOMAIN = "MyPluginFooDomain";
    

    const ,它们将位于标题所包含的翻译单元的本地,因此无需使用 extern 以防止多个定义错误。

        4
  •  2
  •   justin    16 年前

    extern NSString*常量MyPluginErrorDomain;

    或者提供返回静态存储数据的外部函数。例如:

     /* h */ 
    
     extern NSString * MyPluginErrorDomain();
    
     /* m */ 
    
     NSString * MyPluginErrorDomain() {
        static NSString * const s = @"MyPluginErrorDomain";
        return s;
     }
    

    原因是字符串和键通常是通过指针值或哈希值来使用和比较的,而不是真正的字符串比较(isEqualToString:)。

    在代码中,这意味着在多个二进制文件中定义比较的字符串时:

    假设“MyPluginErrorDomain”和“key”具有相同的字符串值,但在不同的二进制文件中定义(即插件主机中的on,插件中的一个)。

    /////// Pointer comparison (NSString)
    BOOL a = [MyPluginErrorDomain isEqualToString:key];
    BOOL b = MyPluginErrorDomain == key;
    
    // c may be false because a may be true, in that they represent the same character sequence, but do not point to the same object
    BOOL c = a == b;
    
    
    /////// Hash use (NSString)
    // This is true
    BOOL d = [MyPluginErrorDomain hash] == [key hash];
    
    // This is indicative if true
    BOOL e = [MyPluginErrorDomain hash] == [someOtherStringKey hash];
    
    // because
    BOOL f = [MyPluginErrorDomain isEqualToString:someOtherStringKey];
    
    // g may be false (though the hash code is 'generally' correct)
    BOOL g = e == f;
    

    哈希代码和指针比较贯穿于字典存储内部的基础和其他Objc技术,键值编码…如果您的字典直接指向xml,这是一回事,但运行时使用是另一回事,在实现和运行时细节中有一些注意事项。