使用-ObjC / -all_load链接器标志时未找到符号

时间:2014-09-23 07:59:32

标签: ios objective-c linker

更新到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];
}

5 个答案:

答案 0 :(得分:2)

我认为您正在使用基础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

答案 1 :(得分:1)

适用于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上另外测试。一切正常。

答案 2 :(得分:1)

change UIKit.framework to optional works to me

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

答案 3 :(得分:0)

UIUserNotificationSettings仅在iOS8上可用

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

答案 4 :(得分:0)

您必须使用小于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标志,它停止了测试类在运行时存在并有选择地使用它的常用技术。

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

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

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

我赞成第一种方法。