基本上,我有以下代码(在此解释:Objective-C Constants in Protocol)
// MyProtocol.m
const NSString *MYPROTOCOL_SIZE;
const NSString *MYPROTOCOL_BOUNDS;
@implementation NSObject(initializeConstantVariables)
+(void) initialize {
if (self == [NSObject class])
{
NSString **str = (NSString **)&MYPROTOCOL_SIZE;
*str = [[MyClass someStringLoadedFromAFile] stringByAppendingString:@"size"];
str = (NSString **)&MYPROTOCOL_BOUNDS;
*str = [[MyClass someStringLoadedFromAFile] stringByAppendingString:@"bounds"];
}
}
@end
我想知道:我有一个类别可以覆盖NSObject的+initialize
方法吗?
答案 0 :(得分:14)
简而言之,不,您无法在类的类别中安全地实现+initialize
方法。如果有现有实现,您将最终替换现有实现,如果一个类的两个类别都实现+initialize
,则无法保证将执行该实现。
+load
具有更多可预测且定义明确的行为,但由于许多事情处于未初始化状态,因此发生任何有用的事情发生得太早。
就个人而言,我完全跳过+load
或+initialize
并使用编译器注释来使函数在加载底层二进制文件/ dylib时执行。不过,那时你几乎无法安全地做到。
__attribute__((constructor))
static void MySuperEarlyInitialization() {...}
为了响应应用程序的启动,您最好不要进行初始化。 NSApplication
和UIApplication
都提供委托/通知挂钩,用于在应用启动时向应用中注入一些代码。
答案 1 :(得分:2)
为什么不在MyClass类中设置这两个变量呢?而且,为什么不使用访问器?不要使用来自无处的伪常量变量,而是在应该实际使用它的类上定义一个访问器。一个简单的+(NSString *)myProtocolSize;即使在协议中也会很棒。
此外,覆盖类别中类的方法“有效”但不可靠,应该不惜一切代价避免:如果您覆盖的方法是在类别中实现的,则运行时不保证加载顺序并且您的实施可能永远不会添加到它。
答案 2 :(得分:0)
类型NSString *const
的变量将始终在代码运行之前初始化,假设我们暂时忽略了C ++的变幻莫测:
NSString *const MY_PROTOCOL_SIZE = @"...";
const NSString *
类型的变量(适用于const
的内容的NSString
关键字,而不是其地址)可以通过任何代码进行修改,但不能将消息发送给它。它违背了制作const
的目的。请考虑使用全局函数:
static NSString *GetMyProtocolSize(void) {
return [[MyClass someStringLoadedFromAFile] ...];
}
或者使用类方法:
@implementation MyClass
+ (NSString *)myProtocolSize {
return [[MyClass someStringLoadedFromAFile] ...];
}
@end
之前您问过一个问题,为什么您的const
字符串不接受动态值 - 这是因为您似乎不了解const
对符号的作用。您应该阅读C中const
关键字的含义,如果const
不正确,应该查看另一种获取字符串的方法。