在某些情况下禁用自动桥接

时间:2017-03-25 22:34:29

标签: objective-c swift

来自Using Swift with Cocoa and Objective-C - Working with Cocoa Frameworks

  

Swift自动将一些Objective-C类型转换为Swift类型,将一些Swift类型转换为Objective-C类型。

但有些情况下,自动桥接是不受欢迎的,例如性能问题或由于桥接实现中的错误。

如何在特定情况下禁用此行为?例如。特定陈述或特定类别。

1 个答案:

答案 0 :(得分:0)

我希望有一个NS_DO_NOT_BRIDGE_FOR_SWIFT宏但唉,它不存在。浏览Swift的源代码,我无法找到禁用桥接的魔术宏。以下答案冗长。它依赖于两个事实:

  1. 核心基础类型(即CF*)未与Swift桥接
  2. Core Foundation(CF*)和Cocoa(NS*)类型之间存在免费桥接
  3. 让我们看一个例子。首先,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
    

    Swift方面

    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运行代码来检查是否存在桥接。