2015-04-18 51 views
1

在我的Facebook的模型类,我有一个函数来检查用户的iOS是否支持Facebook帐户管理:如何检查Xcode 6.3中的Facebook帐户支持?

+ (BOOL)canUseExternalNetwork 
{ 
    return &ACAccountTypeIdentifierFacebook != nil; 
} 

在Xcode 6.3开始,编译器会发出一条错误消息:的

比较解决ACAccountTypeIdentifierFacebook不等于 空指针始终是真实的

首先,我不明白,在一个旧为何一个未定义的常量iOS会解析为大于0的地址。更重要的是,我想解决这个问题而不用黑客:

  • 我不想更改编译器设置来关闭此警告。所有将做的是让我的代码运行,但不能正确运行。
  • 我不想使用iOS版本检查。如果Facebook不再受支持,未来可能会崩溃。我认为Facebook已经停止在他们新的Graph API 2.0中使用本地登录支持。新的SDK不再使用操作系统提供的弹出式登录。相反,它跳转到Facebook应用程序。
  • 适用于任何类型常量的通用解决方案都不错。虽然我现在只需要为Facebook(和Twitter)解决它,但我仍然希望在将来学习如何处理类似的情况。

回答

0

这具有在编译器的轻微的不好的特性(也称为缺陷),使用在框架头文件中定义的符号时为被弱连接不正确评估-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输出。