【问题标题】:Symbol not found when using -ObjC/-all_load linker flags使用 -ObjC/-all_load 链接器标志时找不到符号
【发布时间】:2014-09-23 07:59:31
【问题描述】:

更新到 Xcode6 后,我在 IOS 7 上遇到此代码崩溃,显示为“Symbol not found: _OBJC_CLASS_$_UIUserNotificationSettings”,任何人都可以帮助解决它

if ([application respondsToSelector:@selector(registerUserNotificationSettings:)]){
    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:  (UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert) categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    [[UIApplication sharedApplication] registerForRemoteNotifications];
}
else {
    int notifyType = (UIRemoteNotificationTypeAlert |
                      UIRemoteNotificationTypeBadge |
                      UIRemoteNotificationTypeSound);
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationType)notifyType];
}

编辑: 大家好, 这是运行时崩溃,而不是编译时链接错误,

异常类型:EXC_BREAKPOINT (SIGTRAP) 异常代码:0x0000000000000001、0x00000000e7ffdefe 线程触发:0

Dyld 错误消息: 未找到符号:_OBJC_CLASS_$_UIUserNotificationSettings

我使用的是 Xcode 6.0 (6A313),所以我不应该使用任何 #if 来指示 iOS 版本。此代码在 IOS 8 模拟器上运行良好,但在 IOS 7 设备上崩溃

编辑 2:

最后,这个问题被这些代码解决了,我已经在下面标记了正确的答案,谢谢 trojanfoe。

    if ([application respondsToSelector:@selector(registerUserNotificationSettings:)])
{
    Class userNotifyClass = NSClassFromString(@"UIUserNotificationSettings");
    if(userNotifyClass != nil)
    {
        id notifyInstance = [userNotifyClass settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound) categories:nil];
        [application registerUserNotificationSettings:notifyInstance];
        [application registerForRemoteNotifications];
    }
}
else
{
    int notifyType = (UIRemoteNotificationTypeAlert |
                      UIRemoteNotificationTypeBadge |
                      UIRemoteNotificationTypeSound);
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationType)notifyType];
}

【问题讨论】:

  • “代码崩溃”是指“链接错误”?
  • @Daij-Djan 对不起,我不明白你的意思。
  • 你在 ARM64 上测试吗?
  • 提供屏幕截图、您测试的硬件等。
  • 嗨,Andy,我使用 iTouch 5 和 7.1.1,有效架构 armv7,基础 sdk IOS 8.0。

标签: ios objective-c linker


【解决方案1】:

我认为您正在使用 'base SDK' 7.x 构建您的项目 因此,您可以将其更改为 8.0 或在编译期间检查当前版本:

#if __IPHONE_OS_VERSION_MAX_ALLOWED > __IPHONE_7_1       

    UIUserNotificationSettings *settings = [UIUserNotificationSettings settingsForTypes:  (UIUserNotificationTypeSound | UIUserNotificationTypeBadge | UIUserNotificationTypeAlert) categories:nil];
    [[UIApplication sharedApplication] registerUserNotificationSettings:settings];
    [[UIApplication sharedApplication] registerForRemoteNotifications];
#else
    int notifyType = (UIRemoteNotificationTypeAlert |
                      UIRemoteNotificationTypeBadge |
                      UIRemoteNotificationTypeSound);
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:(UIRemoteNotificationType)notifyType];
#endif

【讨论】:

【解决方案2】:

适用于 XCode 6.1 @ iOS 8 SDK / iOS 7 部署目标。我的应用程序也使用 -ObjC 链接器标志。

刚刚在装有 iOS 7.1.2 / ARMV7 的 iPhone 上运行应用程序。我使用以下代码:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    if([application respondsToSelector:@selector(registerUserNotificationSettings:)]) {
        UIUserNotificationSettings* notificationSettings = [UIUserNotificationSettings settingsForTypes:(UIUserNotificationTypeBadge | UIUserNotificationTypeAlert | UIUserNotificationTypeSound) categories:nil];
        [application registerUserNotificationSettings:notificationSettings];
        [application registerForRemoteNotifications];
    } else {
        [application registerForRemoteNotificationTypes:(UIRemoteNotificationTypeBadge | UIRemoteNotificationTypeAlert | UIRemoteNotificationTypeSound)];
    }
    return YES;
}

更新:在 iPad 4 / iOS 8、iPhone 5s / iOS 8 上进行了额外测试。一切正常。

【讨论】:

    【解决方案3】:

    将 UIKit.framework 更改为我的可选作品

    【讨论】:

      【解决方案4】:

      您必须使用低于 8 的 iOS SDK 版本进行编译才能获得该链接错误。

      要解决此问题,请使用 iOS 8 SDK(即 Xcode 6)并使用以下方法检查该类在运行时是否存在:

      if (NSClassFromString(@"UIUserNotificationSettings")) {
          // do thing
      }
      

      编辑在 OP 提供更多信息后:

      • 他正在使用 Xcode 6 和 iOS 8 SDK。
      • 他正在使用-ObjC-all_load 其他链接器标志

      -ObjC/-all_load 标志阻止了测试类在运行时存在并有选择地使用它的常用技术。

      为了让应用支持 iOS 7 和带有 -ObjC 语义的 iOS 8,我可以想到两个解决方案:

      • 删除使用-ObjC/-all_load 链接器标志以支持-force_load,因为它针对“所有负载”的特定库(请参阅my question here)。
      • 使用更动态(且容易出错)的方法:

        1. 使用NSClassFromString() 创建UIUserNotificationSettings 的实例。
        2. performSelector调用方法。

      我赞成第一种方法。

      【讨论】:

      • 嗨,这是运行时崩溃,是“弱链接”,而不是编译时错误
      • @wangsihao 你在使用-ObjC Other Linker Flag吗?
      • hi trojanfoe,我终于通过您提出的第二种方法“使用更动态(且容易出错)的方法”解决了这个问题。我将把我的代码放在问题的编辑部分。谢谢。
      【解决方案5】:

      UIUserNotificationSettings 仅适用于 iOS8

      if(NSClassFromString(@"UIUserNotificationSettings") != nil) 
      {
          //do your stuff here
      } 
      

      【讨论】:

      • true,但他已经检查了选择器。这是一个链接器错误
      • 是的,但是我这里已经有选择器检查,我也尝试了“NSClassFromString”,仍然是同样错误的崩溃。
      • dyld:找不到符号,运行时链接错误,我有 Xcode 版本 6.0 (6A313),我应该更新到 6.0.1 并尝试一下吗?
      猜你喜欢
      • 1970-01-01
      • 2011-02-23
      • 2013-07-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-01
      • 1970-01-01
      • 2011-04-11
      相关资源
      最近更新 更多