osx – 有没有办法使用基础对象(NSString,NSArray,NSDictionary)在Swift没有桥接?

osx – 有没有办法使用基础对象(NSString,NSArray,NSDictionary)在Swift没有桥接?,第1张

概述使用Swift时,即使框架实际上返回了Objective-C对象,Cocoa框架也被声明为返回本地Swift类型。同样,这些方法将Swift类型作为参数,这在哪里是有意义的。 假设我想调用一个Cocoa方法(在Objective-C中)会给我一个NSArray,然后将它传递给一个采用NSArray的Cocoa方法。有了这样的代码: let a: [AnyObject] = [] // Imagin 使用Swift时,即使框架实际上返回了Objective-C对象,Cocoa框架也被声明为返回本地Swift类型。同样,这些方法将Swift类型作为参数,这在哪里是有意义的。

假设我想调用一个Cocoa方法(在Objective-C中)会给我一个NSArray,然后将它传递给一个采用NSArray的Cocoa方法。有了这样的代码:

let a: [AnyObject] = [] // Imagine calling a method that returns a huge NSArray.let mutable = NSMutableArray()mutable.addobjectsFromArray(a)

它看起来像巨大的NSArray将被分配到一个Swift数组,当被分配给一个然后桥接回NSArray作为一个参数传递。至少这是从分析和查看拆卸看起来如何。

当我不需要在Swift中使用数组时,是否有办法避免这些潜在的慢转换?当我刚从Cocoa接收它然后再传回Cocoa?

起初,我认为这有助于添加类型信息:

let a: NSArray = [] // Imagine calling a method that returns a huge NSArray.let mutable = NSMutableArray()mutable.addobjectsFromArray(a as [AnyObject])

但是后来我必须将参数转换为Swift数组,否则编译器会抱怨。

此外,代码的拆卸如下:

let c: NSArray = mutable.subarrayWithRange(NSMakeRange(0,50))

显示调用__TF10Foundation22_convertNSArrayToArrayurFGSqCSo7NSArray_GSaq__和__TFer10FoundationSa19_brIDgetoObjectiveCurfGSaq__FT_CSo7NSArray,似乎将返回值转换为Swift,然后返回到Objective-C。 (即使发布版本也会发生。)我曾经希望通过键入c作为NSArray,不需要桥接。

我担心这可能导致inefficiencies具有非常大的数据结构,许多不同的常规转换,以及懒惰/代理的集合,因为它们不一定很大,但计算成本可能很高。如果从Swift不能访问,那么可以从Objective-C代码中获得receive这样一个数组,并将其传递回来,而无需实现数组的所有元素。

这是一个非常different performance模型,而不是核心基金会/基金会,桥接是免费的。有很多情况下,代码会传递对象,假设它将是O(1),如果这些对象不可见地改变为O(n),则外部算法可能会变成二次或更差。在这种情况下,我不清楚应该做什么。如果没有办法关闭桥接,似乎所有触及这些对象的东西都需要在Objective-C中重写。

以下是基于上述示例的一些示例时序代码:

NSArray *getArray() {    static NSMutableArray *result;    if (!result) {        NSMutableArray *array = [NSMutableArray array];        for (NSUInteger i = 0; i < 1000000; i++) {            [array addobjectsFromArray:@[@1,@2,@3,@"foo",@"bar",@"baz"]];        }        result = array;    }    return result;}@interface ObjCTests : XCTestCase@end@implementation ObjCTests- (voID)testObjC { // 0.27 seconds    [self measureBlock:^{        NSArray *a = getArray();        NSMutableArray *m = [NSMutableArray array];        [m addobjectsFromArray:a];    }];}@endclass SwiftTests: XCTestCase {    func testSwift() { // 0.33 seconds        self.measureBlock() {            let a: NSArray = getArray() as NSArray            let m = NSMutableArray()            m.addobjectsFromArray(a as [AnyObject])        }    }    func testSwiftPure() { // 0.83 seconds        self.measureBlock() {            let a = getArray()            var m = [AnyObject]()            m.appendContentsOf(a)        }    }}

在这个例子中,testSwift()比testObjC()慢约22%。只是为了好玩,我尝试用本地Swift数组进行数组追加,而这慢得多。

一个相关的问题是,当Objective-C代码通过Swift代码一个NSMutableString时,Swift String结束了一个可变字符串的副本。这在Swift的背后不会意外突变的意义上是好的。但是,如果你需要做的只是将一个字符串传递给Swift并简要地看一下,这个副本可能会增加意外的开销。

你试过扩展吗?
extension NSMutableArray{    func addobjectsFromNSArray(array:NSArray)    {         for item in array         {              self.addobject(item);         }    }}

现在我有时间真的玩这个,而不是在理论上说话,我要修改我的答案

创建扩展名,而是在目标c文件中执行

@interface NSMutableArray(Extension)    - (voID)addobjectsFromNSArray:(NSObject*) array;@end@implementation NSMutableArray(Extension)    - (voID)addobjectsFromNSArray:(NSObject*) array{   [self addobjectsFromArray:(NSArray*)array];}@end

我发现代码的工作速度要快很多,这样做。 (从我的测试几乎两倍)

testSwift 4.06秒

testSwiftPure 7.97秒

testSwiftExtension 2.30秒

总结

以上是内存溢出为你收集整理的osx – 有没有办法使用基础对象(NSString,NSArray,NSDictionary)在Swift没有桥接?全部内容,希望文章能够帮你解决osx – 有没有办法使用基础对象(NSString,NSArray,NSDictionary)在Swift没有桥接?所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://www.54852.com/web/1053327.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-25
下一篇2022-05-25

发表评论

登录后才能评论

评论列表(0条)

    保存