不明白NSClassFromString如何用于条件调用

Gru*_*kes 5 ios

我的项目中有一个测试类,在开发阶段就在那里,但是会针对app store构建编译出来.

我在几本书中读到,NSClassFromString可用于确定一个类是否存在,其示例代码如下:

if (NSClassFromString(@"SomeClass") != nil)
{
[SomeClass someMethod];
}
else
{
code not using SomeClass
}
Run Code Online (Sandbox Code Playgroud)

但是在我的项目中实现这一点之后,我发现我在目标中遇到链接错误,我删除了包含SomeClass的源文件.

因此,我的结论是,这种用于确定类的存在/不存在的机制仅在该类位于您正在使用其他类的库或源文件中时才有用(提及此技术的书中缺少一个细节).或者我错过了什么?

Tom*_*mmy 6

NSClassFromString在运行时搜索命名类.事实上,它将确定该类是否存在.

为了使编译器成功地获取过去的静态引用,[SomeClass someMethod]它需要链接的东西.

你是正确的,因此当你链接到像Foundation这样的东西时,这个机制可以工作,Apple在那里增加了一个额外的类,比如检查是否NSJSONSerialization存在.

如果您对可能存在或不存在的框架进行弱链接,它也可以工作.因此,例如,您可能会弱化与Twitter.framework和使用的链接[TWRequest alloc] ....您仍然可以在没有Twitter框架的iOS 4上构建和部署.

Apple实际上已经略微修改了库的存储方式,并且正在转换为允许if([TWRequest class])或者用于代替显示NSClassFromString弱链接的显式位置.

但是在你的情况下,听起来你想要链接到静态库或不链接到它?因此,类可能在运行时可用,也可能不可用,但链接器可能也可能不可见?

在这种情况下,您只需要避免对元类的文字引用.所以你可以这样做:

Class someClassMetaClass = NSClassFromString(@"SomeClass");

if(someClassMetaClass)
{
    SomeClass *instance = [[someClassMetaClass alloc] init];
    /* ... */
}
Run Code Online (Sandbox Code Playgroud)

只要头文件可见,编译器就会很高兴允许您指定SomeClass指针的类型(因为它不会进入二进制文件),并且能够针对已发布的接口建议通常的自动完成和警告.只需确保始终通过指向Class从运行时获得的指针而不是直接指向元类.这样,链接器无需跟进.