如何在Xcode 6.3中检查Facebook帐户支持?

时间:2015-04-18 15:17:21

标签: objective-c xcode cocoa-touch xcode6

在我的Facebook模型类中,我有一个功能来检查用户的iOS是否支持Facebook帐户管理:

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

从Xcode 6.3开始,编译器会出错:

  

地址ACAccountTypeIdentifierFacebook的比较不等于   空指针始终为true

首先,我不明白为什么旧的iOS上的未定义常量会解析为大于0的地址。更重要的是,我想在没有黑客的情况下修复此问题:

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

1 个答案:

答案 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的结果输出中。