我可以在静态库中扩展 NSString 类并在带有 Swift 的 App 中使用它吗?

Posted

技术标签:

【中文标题】我可以在静态库中扩展 NSString 类并在带有 Swift 的 App 中使用它吗?【英文标题】:Could I extend NSString class in Static Library and use it in App with Swift? 【发布时间】:2018-05-24 12:17:10 【问题描述】:

我在自定义静态库 CommonLib 中扩展了 NSString:

//NSString+ext.h
#import <Foundation/Foundation.h>

@interface NSString (ext)
- (BOOL)isContainsEmoji;
@end



//NSString+ext.m
#import "NSString+ext.h"

@implementation NSString (ext)
- (BOOL)isContainsEmoji
    //Do Something...

@end

因为CommonLib包含一些Swift代码文件,所以我在CommonLib项目中创建了一个桥接头文件CommonLib-Bridging-Header.h:

//in CommonLib-Bridging-Header.h
#import "NSString+ext.h"

接下来,我将 CommonLib 链接到我的 App 项目,并在 App 项目中创建一个新文件 Node.swift:

//Node.swift
import Foundation
import CommonLib

class Node

    var name:String!
    var isBadName:Bool
        let tmpString = name as NSString
        return tmpString.isContainsEmoji()
    

最后,我在我的应用程序的某个地方使用它:

//In my UIViewController class
override func viewDidAppear(...)
    super.viewDidAppear(...)

    let node = Node()
    node.name = "panda hopy"
    print("\(node.isBadName)") //Crash in this line!!!

此时编译就OK了!!!但是当我运行应用程序时它崩溃了:

由于未捕获的异常“NSInvalidArgumentException”而终止应用,原因:“-[Swift._NSContiguousString isContainsEmoji]:无法识别的选择器发送到实例 0x60400084b340”

那么这里有什么问题吗???以及如何解决它???谢谢;)

(PS:我的环境Xcode 9.3.1 swift 4.1)

【问题讨论】:

你不能在库中使用桥接头,这意味着你可以在 Objective-C 中使用 swift,但反之则不行。 你的意思是删除桥接头文件,它会工作??? 更重要的是你可以有一个桥接头,它只是在静态或动态库中被忽略。混合的 Objective-C 和 Swift 不支持库和框架。一个苹果开发者直接告诉我这个。 谢谢,但如何解决? 您可以为您的 swift 和 Objective-c 组件使用单独的框架。或者你可以让 Objective-C 只调用 swift 而从不调用。您可以通过使用动态实例化和使用 swift 中定义的协议来解决这个问题......但要小心突然出现的引用计数问题。 【参考方案1】:

最后,我很高兴解决了这个问题 ;)

很简单,在App项目中添加链接选项:

-all_load

没关系,你可以参考这个:

unrecognized selector sent to instance” to a static library despite ObjC flag

谢谢大家;)

【讨论】:

以上是关于我可以在静态库中扩展 NSString 类并在带有 Swift 的 App 中使用它吗?的主要内容,如果未能解决你的问题,请参考以下文章

Flink Gelly 扩展边缘类并在 DataSet 中使用

静态库中的外部指针为空,当不是静态库时工作正常

如何列出具有 .o 扩展名的静态库中的文件名

如何在静态库中编译程序?

密码学 - 发布模式下的奇怪行为

如何从应用程序域中所有加载的程序集中获取所有静态类并使用反射调用静态方法