在我的Facebook模型类中,我有一个功能来检查用户的iOS是否支持Facebook帐户管理:
+ (BOOL)canUseExternalNetwork
{
return &ACAccountTypeIdentifierFacebook != nil;
}
从Xcode 6.3开始,编译器会出错:
地址ACAccountTypeIdentifierFacebook的比较不等于 空指针始终为true
首先,我不明白为什么旧的iOS上的未定义常量会解析为大于0的地址。更重要的是,我想在没有黑客的情况下修复此问题:
答案 0 :(得分:0)
这在编译器中具有轻微错误(也称为错误)的所有标记,当使用框架头中定义的符号作为弱链接时,它没有正确评估
-weak_framework
,并且因此认为代码是无操作。
这意味着优化器很高兴能够删除来自代码的if检查 - 当我使用简单的测试代码时它会这样做。
#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
的结果输出中。