简体   繁体   English

如果从 Swift 中的 NSObject 继承,为什么一个类会变成公共的?

[英]Why does a class become public if you inherit from NSObject in Swift?

I'm working on a framework.我正在研究一个框架。

The library is written in Swift and I notice that when a class inherits from NSObject or conforms to NSObjectProtocol , its declaration can be found in *.framework/Headers/*-Swift.h .该库是用 Swift 编写的,我注意到当一个类继承自NSObject或符合NSObjectProtocol ,它的声明可以在*.framework/Headers/*-Swift.h

This class is available outside of the module in Objective-C code, so it became public.此类在 Objective-C 代码中的模块之外可用,因此它成为公开的。

Why does it happen if the access level is internal?如果访问级别是内部的,为什么会发生这种情况?

Internal Swift classes need to be available to the Objective-C code of that framework, however the only way Objective-C code can access the Swift classes is by importing the -Swift.h header file.内部 Swift 类需要可用于该框架的 Objective-C 代码,但是 Objective-C 代码可以访问 Swift 类的唯一方法是导入-Swift.h头文件。

Now, how can a Swift class be visible to Objective-C: it either needs to inherit NSObject , or conform to NSObjectProtocol .现在,Swift 类如何对 Objective-C 可见:它要么需要继承NSObject ,要么符合NSObjectProtocol If any of these two conditions is fulfilled, and the class declaration is not decorated with @nonobjc / private / fileprivate , then it will be exported to Objective-C via the -Swift.h module header.如果满足这两个条件中的任何一个,并且类声明没有用@nonobjc / private / fileprivate ,那么它将通过-Swift.h模块头文件导出到 Objective-C。

This is why any Swift classes that are exportable to Objective-C will automatically be present in the discussed header file.这就是为什么任何可导出到 Objective-C 的 Swift 类都会自动出现在所讨论的头文件中的原因。 It's an (unfortunate) coincidence that for frameworks this results in the class being publicly available (due to the fact that any Objective-C declarations that appear in a header are public).对于框架来说,这是一个(不幸的)巧合,这导致类是公开可用的(因为出现在标题中的任何 Objective-C 声明都是公开的)。

Now, if you want your class to not end up in the -Swift.h header file, but still want to keep the NSObject(Protocol) inheritance/conformance, a workaround would be to make your class generic, thus prohibiting its exposure to Objective-C.现在,如果您不希望您的类最终出现在-Swift.h头文件中,但仍希望保持NSObject(Protocol)继承/一致性,则一种解决方法是使您的类具有通用性,从而禁止其暴露于 Objective -C。 Note that this will also prevent the class from being available to Objective-C code in the same framework.请注意,这也将阻止该类可用于同一框架中的 Objective-C 代码。

// the generic argument doesn't matter, it's only used to make the class
// Swift-only
class MyClass<T>: NSObject { }

The caveat would be that every time the class is used, you will need to specify a value for the generic argument.需要注意的是,每次使用该类时,您都需要为泛型参数指定一个值。 This can be avoided by adding an intermediary base class:这可以通过添加一个中间基类来避免:

// just a class that inherits NSObject, but is not exported in the -Swift header
class Empty<T>: NSObject { }

class MyClass: Empty<String> { }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM