2017-03-25 62 views
2

Using Swift with Cocoa and Objective-C - Working with Cocoa Frameworks从禁用自动桥接:在某些情况下

夫特自动转换一些Objective-C的类型夫特类型,以及一些夫特类型Objective-C的类型。

但有些情况下,自动桥接是不可取的,如性能问题或桥接实施中的错误。

如何在特定情况下禁用此行为?例如。为特定的声明或特定的类。

+0

只有在Swift中使用Swift类型并且与Objective-C类型接口时才会发生这种情况。例如,如果你在Swift中使用'Array'并且请求产生'NSArray'的东西,'NSArray'将会桥接到Swift'Array'。如果你直接在Swift中使用'NSArray',虽然不会发生桥接。这不包括你的用例吗? –

+0

@ItaiFerber当我要求产生'NSArray'的东西时,我想获得'NSArray'(跳过桥接到'Array')。 – mixel

+0

'let myArray:NSArray = thingWhichProducesNSArray()'不会桥接 –

回答

0

我希望有一个NS_DO_NOT_BRIDGE_FOR_SWIFT宏,但唉,它不存在。通过Swift的源代码徘徊,我无法找到禁用桥接的魔术宏。以下答案是详细的。它依赖于2个事实:

  1. 核心基础类型(即CF*)没有桥接到斯威夫特
  2. 有核心基金会(CF*)可可(NS*)类型的免费桥接和

我们来看一个例子。首先,Objective-C的一面:

// MyClass.h 
@interface MyClass : NSObject 

NS_ASSUME_NONNULL_BEGIN 
- (NSArray *) randomNumbers NS_SWIFT_UNAVAILABLE(""); // mark this method as unavailable in Swift 
- (CFArrayRef) cfRandomNumbers NS_REFINED_FOR_SWIFT; // tell the compiler that you have a refined version for Swift 
NS_ASSUME_NONNULL_END 

@end 

// MyClass.m 
#import "MyClass.h" 

@implementation MyClass 

- (NSArray *) randomNumbers { 
    return @[ @1, @2, @3 ]; 
} 

- (CFArrayRef) cfRandomNumbers { 
    return CFBridgingRetain([self randomNumbers]); // toll-free 
} 

@end 

雨燕侧

extension MyClass { 
    // Even though we marked `randomNumbers` as unavailable in Swift, we can't 
    // use the same signature. Must name it something else. 
    func objcRandomNumbers() -> NSArray { 
     // Methods marked with NS_REFINED_FOR_SWIFT pick up 
     // double-underscore prefix in their names 
     return __cfRandomNumbers().takeUnretainedValue() as NSArray 
    } 
} 

let obj = MyClass() 
let arr = obj.objcRandomNumbers() // no bridging here 

好处是一切都记录在案,因此 “官方”。您可以通过Profiler运行代码来检查桥接是否已经发生。