Objective-C 库类别方法在 Swift 应用程序环境中不起作用

标签 objective-c swift ios8 categories xcode6.3

我有一个 Objective-C iOS 应用程序,它由一个工作区 (AuthPort.xcworkspace) 和一个项目 (AuthPort.xcodeproj) 和一个构建名为“libAnet SDK”的库的 Objective-C SDK 项目(“ANet SDK.xcodeproj”) 组成。一个”)。

“libAnet SDK.a”与 AuthPort 目标构建阶段链接。

在 SDK 中,NSString 上有一些类别被内置到“libAnet SDK.a”中。它们被命名为:

NSString+stringWithXMLTag.h 和 NSString+stringWithXMLTag.m
.
.
.
等等。

AuthPort.xcodeproj 中的一些代码调用库中的代码,而库中的代码又调用这些类别方法。

在上述 Objective-C 环境中一切顺利!

现在......我正在使用新项目在新工作区中用 Swift 重写 AuthPort 代码,并且还使用构建“libAnet SDK.a”的 Objective-C SDK

因此,我创建了一个名为 AuthPort.xcodeproj 的新 Swift Xcode 项目,并将其添加到名为 AuthPort.xcworkspace 的新工作区中。我还在项目中添加了 authorize.net SDK(“ANet SDK.xcodeproj”,用 Objective-C 编写)。

到现在为止还挺好。我创建了一个 AuthPort-Bridging-Header.h 文件并从 SDK 导入了所有标题(没有类别标题 - 稍后会详细介绍)。我还在 AuthPort 目标的构建阶段中链接了“libAnet SDK.a”。

AuthPort 构建和运行时没有错误或警告。

现在,在主 View Controller 的 viewDidLoad 中,我添加了代码来访问库方法以向公司 authorize.net 注册新设备:

var r: MobileDeviceRegistrationRequest = MobileDeviceRegistrationRequest()

an.mobileDeviceRegistrationRequest(r)

这两个调用在 Objective-C 和 Swift 版本中是相同的库方法。最后一个方法调用其他库方法,这些方法调用上面 NSString 类别的方法。

当我在 Objective-C 环境中的类别方法中放置断点(应用程序和库中的所有 Objective-C 代码)时,程序会按预期中断,我可以单步执行代码。

当我在 Swift 环境(带有 Objective-C 库的 Swift 应用程序项目)中的类别方法中放置断点时,调试器永远不会进入类别方法。在执行的某一时刻,应用程序 SIGABRT 具有以下内容:
2015-04-21 12:25:47.388 AuthPort[4743:2404231] +[NSString stringWithXMLTag:andValue:]: unrecognized selector sent to class 0x38450e18

2015-04-21 12:25:47.390 AuthPort[4743:2404231] * 由于未捕获的异常“NSInvalidArgumentException”而终止应用程序,原因:“+[NSString stringWithXMLTag:andValue:]: unrecognized selector sent to class 0x38450e18”
*
首先抛出调用堆栈:
(0x29a0a5a7 0x3792fc77 0x29a0f989 0x29a0d949 0x2993eb68 0xd9e4b 0xc301f 0xdd507 0xc4725 0xc44b1 0xb8f28 0xb9e60 0x2cf0eb65 0x2cf0e8d5 0x2d031c43 0x2d031ac7 0x2d03196b 0x2cf1b5f1 0x2d0357b3 0x2d03491f 0x2cf2433b 0x2cf159e1 0x2cf15003 0x2cf14e6b 0x2cf148ef 0x2cf121ef 0x2cf7c031 0x2d16e34f 0x2d170781 0x2d17b1a9 0x2d16f063 0x302880a1 0x299d125d 0x299d0521 0x299cecbf 0x2991bb51 0x2991b963 0x2cf72b8f 0x2cf6dc91 0xb5290 0x37ed8aaf)
libc++abi.dylib:以 NSException 类型的未捕获异常终止
(lldb)

[NSString stringWithXMLTag:andValue:] 来自库添加到 NSString 的类别。

库方法 stringOfXMLRequest 调用类别方法 stringWithXMLTag:andValue:
- (NSString *) stringOfXMLRequest {

NSString *s = [NSString stringWithFormat:@""
               @"<merchantAuthentication>"
               @"%@"        //name (optional)
               @"%@"        //fingerPrint type Object                                      @"%@"        //transactionKey or
               @"%@"        //sessionToken or
               @"%@"        //password
               @"%@"        //mobileDeviceId (optional)
               @"</merchantAuthentication>",
               (self.name ? [NSString stringWithXMLTag:@"name" andValue:self.name] : @""),
               (self.fingerPrint ? [self.fingerPrint stringOfXMLRequest] : @""),
               (self.transactionKey ? [NSString stringWithXMLTag:@"transactionKey" andValue:self.transactionKey] : @""),
               (self.sessionToken ? [NSString stringWithXMLTag:@"sessionToken" andValue:self.sessionToken] : @""),
               (self.password ? [NSString stringWithXMLTag:@"password" andValue:self.password] : @""),
               (self.mobileDeviceId ? [NSString stringWithXMLTag:@"mobileDeviceId" andValue:self.mobileDeviceId] : @"")];

return s;

}

SIGABRT 不会发生,直到第二次调用 stringWithXMLTag:andValue: 以获得 transitionKey。

完全相同的库代码在两种环境中运行。

这是来自 stringWithXMLTag:andValue: 的代码,它在调试器中从未见过:
+ (NSString *)stringWithXMLTag:(NSString *)t andValue:(NSString *)v {
if (v == nil) {
    return @"";
}
else { 
    v = [NSString stringWithEscapedXMLValue:v];
    return [NSString stringWithFormat:@"<%@>%@</%@>", t, v, t];
}

}

问题仅在库代码中,其中库方法调用另一个库方法,该库方法调用库类别方法,该方法从未在 Swift 版本的调试器中输入。

我还尝试在桥接头中添加类别头文件,并将 -ObjC 和 -all_load 添加到 AuthPort 的其他链接器标志中。没有运气。

我已经在网上搜索了 2 天,但没有运气。希望你们中的一个人会看到这种行为。

我正在使用 Xcode 6.3 和 iOS 8.3(在 iOS 8.2 上部署)进行构建。

谢谢。

最佳答案

检查:

  • 您已将类别添加到框架项目的 Umbrella 框架中。使用#import "your.h"
  • 我已将该类别中的 .h 文件标记为公开。选择 .h > Identity and Type > Target Membership > Public
  • 在您的项目中,设置正确的框架搜索路径
  • 关于Objective-C 库类别方法在 Swift 应用程序环境中不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29764367/

    相关文章:

    iphone - 如何获取 UIImage 中使用的图像名称?

    ios - 实现 JBChartView 时遇到问题

    ios - XCTAssert 中断函数

    testing - 与 iOS 8 的内部测试人员进行 Beta 测试

    objective-c - #导入中的#导入?

    swift - 快速计算分数

    ios - 继续记录丢失的服务器连接以获取 kct 连接无效通知

    ios - iOS8 在搜索栏中输入文本时出现错误

    objective-c - 如何制作枚举案例的开关案例(快速)

    ios - 在 Objective-C 中调用 Magento SOAP API 时出错