Почему класс становится общедоступным, если вы наследуете от NSObject в Swift? - PullRequest
0 голосов
/ 26 января 2019

Я работаю над фреймворком.

Библиотека написана на языке Swift, и я заметил, что когда класс наследует от NSObject или соответствует NSObjectProtocol, его объявление можно найти в *.framework/Headers/*-Swift.h.

Этот класс доступен вне модуля в коде Objective-C, поэтому он стал общедоступным.

Почему это происходит, если уровень доступа является внутренним?

1 Ответ

0 голосов
/ 26 января 2019

Внутренние классы Swift должны быть доступны для кода Objective-C этого фреймворка, однако единственный способ, которым код Objective-C может получить доступ к классам Swift, - это импортировать файл заголовка -Swift.h.

ТеперьКак класс Swift может быть видим для Objective-C: он должен либо наследовать NSObject, либо соответствовать NSObjectProtocol.Если какое-либо из этих двух условий выполнено и объявление класса не декорировано @nonobjc / private / fileprivate, то оно будет экспортировано в Objective-C через заголовок модуля -Swift.h.

Вот почему любые классы Swift, которые можно экспортировать в Objective-C, будут автоматически присутствовать в обсуждаемом заголовочном файле.Это (к сожалению) совпадение, что для каркасов это приводит к тому, что класс становится общедоступным (из-за того, что любые объявления 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> { }
...