Корректное использование уровней доступов в Swift способно скрыть детали реализации вашего кода от посторонних глаз от кода в других файлах и модулях. Очень часто именно с этой темы начинается собеседование iOS разработчика.
В нашем распоряжении пять уровней доступа:
- Open;
- Public;
- Internal;
- Private;
- File-private.
К сожалению, не помню ресурс-источник следующей картинки, но по ней очень легко понять тему контроля доступа:
Open — это наивысший уровень доступа. Он позволяет получить доступ к объекту как в целевом модуле, так и за его пределами. Вы можете создать подкласс или переопределить open-объект в любом модуле.
Public — то же самое, что и Open. Отличие в том, что Public доступ позволяет переопределять и создавать подкласс объекта только внутри целевого модуля (Target). Другими словами, доступ к объекту из других модулей остается.
Internal — этот уровень доступа используется по умолчанию в Swift. На уровне Internal доступ к объекту есть только внутри текущего модуля. Соответственно, создание подклассов и переопределение доступно тоже только в текущем модуле.
File-private — на этом уровне у вас есть доступ к элементам данных и функциям в рамках текущего файла. Обычно используется, когда в текущем исходном файле необходимо скрыть реализацию.
Private — это самый низкий уровень доступа. Если декларация или расширение текущего файла включает сущность, то Private set ограничивает ее использование. У вас нет контроля доступа в подклассах или в других файлах.
Синтаксис уровней доступа
Чтобы установить уровень доступа, необходимо поместить его перед объявлением объекта:
public class PublicClass {}
internal class InternalClass {}
fileprivate class FilePrivateClass {}
private class PrivateClass {}
Как говорилось ранее, если не указать уровень доступа, то по умолчанию будет стоять дефолтный уровень internal.
Разница между уровнями доступа Open и Public (вопрос на собеседовании)
Обычно на собеседовании спрашивают разницу либо между Open и Public, либо между Private и Fileprivate доступами.
На самом деле уровни доступа Open и Public сильно отличаются друг от друга. Уровень доступа Open необходим для ограничения на наследование классов в Swift. Это означает, что уровень Open можно применить только к классам и членам класса (свойства и методы).
Open класс может быть подклассом в модуле, в котором он определен. Также он может быть подклассом в модулях, которые импортируют модуль с нашим классом. То же самое относится и к open членам класса.
Public классы могут быть подклассами только в модуле, в котором они определены. То же самое относится к public членам класса.
Пример с уровнем доступа Open
Если на собеседовании вас попросят привести пример реализации с уровнем доступа Open, то вы смело можете рассказать про Core Data.
@available(iOS 3.0, *)
open class NSManagedObject : NSObject {
@available(iOS 3.0, *)
open class var contextShouldIgnoreUnmodeledPropertyChanges: Bool { get }
@available(iOS 10.0, *)
open class func entity() -> NSEntityDescription
...
Если бы Apple использовали тип доступа public к методам класса NSManagedObject, то разработчики не смогли бы переопределять все эти методы в своих NSManagedObject подклассах. Именно для этого и предназначено разделение на public и open уровни доступа.
Разница между уровнями доступа Private и Fileprivate (вопрос на собеседовании)
С этим вопросом немного проще. Private дает доступ к членам данных и функциям в рамках их объявления или расширения в текущем файле. Fileprivate дает доступ к членам данных и функциям в одном и том же исходном файле или в подклассе/расширении.
// Объявляем класс А с двумя переменными
class A {
private var aPrivate: String?
fileprivate var aFileprivate: String?
func accessMySelf() {
// Доступ к переменным будет работать корректно
self.aPrivate = ""
self.aFileprivate = ""
}
}
// Объявляем класс B (в том же файле) для доступа к классу А
class B {
func accessA() {
// Создаем экземпляр класса A
let aObject = A()
// Ошибка — нет доступа
aObject.aPrivate = "Error"
// Доступ есть
aObject.aFileprivate = "Access"
}
}
Дополнительный материал:
Выразить благодарность или найти уникальный материал вы можете в boosty.
Подписывайтесь на мой Telegram-канал iOS Interview Channel, чтобы не пропустить новый материал.