繁体   English   中英

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

[英]What is the best way to define string constants in an objective-c protocol?

我已经定义了一个我的所有插件必须实现的协议。 我也希望所有插件都使用某些字符串,比如MyPluginErrorDomain。 使用整数这很容易在枚举中实现,但我无法弄清楚如何用字符串做同样的事情。 通常,在课程中我会定义

extern NSString * const MyPluginErrorDomain;

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

NSString * const MyPluginErrorDomain = @"MyPluginErrorDomain";

但是这在协议中不能很好地工作,因为每个插件都必须提供自己的实现,这违背了具有常量的目的。

然后我试过了

#define MYPLUGIN_ERROR_DOMAIN @"MyPluginErrorDomain"

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

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

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

你保留.h定义:

extern NSString * const MyPluginErrorDomain;

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

NSString * const MyPluginErrorDomain = @"MyPluginErrorDomain";

所以插件仍然可以实现接口,但是在编译时,它们会在你的其他.m文件中链接或编译,所以他们会看到MyPluginErrorDomain的值。

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

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

请注意,由于指针是const ,它们将是标头为#included的转换单元的本地,因此不需要使用extern来防止多个定义错误。

您应该将其实现为extern字符串,如示例中所示:

extern NSString * const MyPluginErrorDomain;

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

 /* h */ 

 extern NSString * MyPluginErrorDomain();

 /* m */ 

 NSString * MyPluginErrorDomain() {
    static NSString * const s = @"MyPluginErrorDomain";
    return s;
 }

原因是字符串和键经常被使用并通过指针值或散列值进行比较,而不是真正的字符串比较(isEqualToString :)。

在实施层面,两者之间存在很大差异:

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

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

/////// 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,这是一回事,但运行时使用是另一回事而且有一些在实现和运行时细节中提出警告。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM