这具有在编译器的轻微的不好的特性(也称为缺陷),使用在框架头文件中定义的符号时为被弱连接不正确评估-weak_framework
的所有特征,并且这样认为该代码是无效的。
这意味着优化是高兴地能够删除的,如果检查从代码 - 它不这样做,当我用一个简单的测试一段代码。
#import <Accounts/ACAccountType.h>
#import <stdio.h>
int
main(int argc, char **argv)
{
if (&ACAccountTypeIdentifierFacebook != NULL)
NSLog(@"Hello\n");
return (0);
}
此代码编译:
$ clang -weak_framework Accounts -framework Foundation weak.m
weak.m:8:10: warning: comparison of address of 'ACAccountTypeIdentifierFacebook' not equal to a null pointer is always true [-Wtautological-pointer-compare]
if (&ACAccountTypeIdentifierFacebook != NULL)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~
1 warning generated.
当检查,表明ACAccountTypeIdentifierFacebook
符号不即使在代码中引用:
$ nm -m a.out
(undefined) external _NSLog (from Foundation)
(undefined) external ___CFConstantStringClassReference (from CoreFoundation)
0000000100000000 (__TEXT,__text) [referenced dynamically] external __mh_execute_header
0000000100000f40 (__TEXT,__text) external _main
(undefined) external dyld_stub_binder (from libSystem)
即优化器除去它完全。您可以使用otool -tv a.out
来检查结果代码,并且您会看到if测试完全被忽略。
希望它将在未来版本的编译器中得到修复,但是您可以暂时解决此问题。
为了让编译器能够把符号要弱,需要明确地标记为weak import,这意味着它需要看起来像:
extern NSString * const ACAccountTypeIdentifierFacebook __attribute__((weak_import));
这意味着代码看起来像:
if (&ACAccountTypeIdentifierFacebook != NULL) {
NSLog(@"Have Facebook");
}
然后将正常工作。如果我们在示例代码的开始处添加一行这样的代码并编译它,我们会看到它编译时没有问题,并且符号出现在nm -m a.out
的输出中,并且if测试出现在结果中从otool -tv a.out
输出。