我正在研究一个框架。
该库是用 Swift 编写的,我注意到当一个类继承NSObject
或符合 时NSObjectProtocol
,它的声明可以在*.framework/Headers/*-Swift.h
.
这个类在 Objective-C 代码中的模块之外可用,所以它变成了公共的。
如果访问级别是内部的,为什么会发生这种情况?
我正在研究一个框架。
该库是用 Swift 编写的,我注意到当一个类继承NSObject
或符合 时NSObjectProtocol
,它的声明可以在*.framework/Headers/*-Swift.h
.
这个类在 Objective-C 代码中的模块之外可用,所以它变成了公共的。
如果访问级别是内部的,为什么会发生这种情况?
内部 Swift 类需要可用于该框架的 Objective-C 代码,但是 Objective-C 代码访问 Swift 类的唯一方法是导入-Swift.h
头文件。
现在,Swift 类如何对 Objective-C 可见:它要么需要继承NSObject
,要么符合NSObjectProtocol
. 如果满足这两个条件中的任何一个,并且类声明没有用@nonobjc
/ private
/修饰fileprivate
,那么它将通过-Swift.h
模块头导出到 Objective-C。
这就是为什么任何可导出到 Objective-C 的 Swift 类都会自动出现在所讨论的头文件中的原因。这是一个(不幸的)巧合,对于框架来说,这会导致类是公开可用的(因为出现在标头中的任何 Objective-C 声明都是公开的)。
现在,如果您希望您的类不在-Swift.h
头文件中结束,但仍希望保持NSObject(Protocol)
继承/一致性,则一种解决方法是使您的类通用,从而禁止其暴露于 Objective-C。请注意,这也将阻止该类可用于同一框架中的 Objective-C 代码。
// the generic argument doesn't matter, it's only used to make the class
// Swift-only
class MyClass<T>: NSObject { }
需要注意的是,每次使用该类时,您都需要为泛型参数指定一个值。这可以通过添加中间基类来避免:
// just a class that inherits NSObject, but is not exported in the -Swift header
class Empty<T>: NSObject { }
class MyClass: Empty<String> { }