import
.
open
, public
, internal
, fileprivate
, private
:
public class SomePublicClass {}
internal class SomeInternalClass {}
fileprivate class SomeFilePrivateClass {}
private class SomePrivateClass {}
public var somePublicVariable = 0
internal let someInternalConstant = 0
fileprivate func someFilePrivateFunction() {}
private func somePrivateFunction() {}
SomeInternalClass
и someInternalConstant
могут быть записаны без явного модификатора уровня доступа и всё будут иметь внутренний уровень доступа:
class SomeInternalClass {} // неявный internal
let someInternalConstant = 0 // неявный internal
public class SomePublicClass {
// явный public class
public var somePublicProperty = 0
// явный public class member
var someInternalProperty = 0
// неявный internal class member
fileprivate func someFilePrivateMethod() {}
// явный file-private class member
private func somePrivateMethod() {}
// явный private class member
}
class SomeInternalClass {
// неявный internal class
var someInternalProperty = 0
// неявный internal class member
fileprivate func someFilePrivateMethod() {}
// явный file-private class member
private func somePrivateMethod() {}
// явный private class member
}
fileprivate class SomeFilePrivateClass {
// явный file-private class
func someFilePrivateMethod() {}
// неявный file-private class member
private func somePrivateMethod() {}
// явный private class member
}
private class SomePrivateClass {
// явный private class
func somePrivateMethod() {}
//неявный private class member
}
someFunction()
без указания явного модификатора доступа для этой функции. Вы можете ожидать, что эта функция будет иметь внутренний уровень доступа, но это не тот случай. На самом деле функция someFunction()
не скомпилируется в виде, в котором она написана ниже:
func someFunction() -> (SomeInternalClass, SomePrivateClass) {
// function implementation goes here
}
Возвращаемый тип функции является кортежем из двух классов. Один из этих классов был определён как внутренний, а другой - как приватный. Следовательно, весь уровень доступа составного типа кортежа будет приватным (минимальный уровень доступа составляющих кортеж типов).
private
для того, чтобы объявление функции было корректным:
private func someFunction() -> (SomeInternalClass, SomePrivateClass) {
// function implementation goes here
}
Некорректно пометить определение someFunction()
модификаторами public
или internal
или использовать стандартное значение внутренного доступа, так как публичные или внутренние пользователи функции могут не иметь соответствующего доступ к приватному классу, используемому в возвращаемом типе функции.
CompassPoint
имеет явный уровень доступа публичный. Кейсы перечисления north
, south
, east
и west
как следствие будут иметь публичный уровень доступа:
public enum CompassPoint {
case north
case south
case east
case west
}
private
в качестве чистого значения для перечисления с уровнем доступа internal
.
someMethod()
. Класс B - это подкласс класса A со сниженным уровнем доступа до внутреннего. Однако класс B предоставляет перезапись метода someMethod()
с уровнем доступа внутренним, который выше чем у оригинальной реализации someMethod()
:
public class A {
fileprivate func someMethod() {}
}
internal class B: A {
override internal func someMethod() {}
}
public class A {
fileprivate func someMethod() {}
}
internal class B: A {
override internal func someMethod() {
super.someMethod()
}
}
Так как надкласс A и подкласс B определены в одном исходном файле, то реализации B корректно в методе someMethod()
вызвать super.someMethod()
.
private
:
private var privateInstance = SomePrivateClass()
fileprivate(set)
, private(set)
или internal(set)
перед вводными словами var
или subscript
.
fileprivate(set)
, private(set)
или internal(set)
для изменения уровня доступа для этого синтезированного сеттера тем же способом, что и для явного сеттера в вычисляемом свойстве.
TrackedString
, которая отслеживает количество раз, сколько было модифицировано строковое свойство:
struct TrackedString {
private(set) var numberOfEdits = 0
var value: String = "" {
didSet {
numberOfEdits += 1
}
}
}
Структура TrackedString
определяет хранимое свойство с названием value
, которое имеет изначальное значение "" (пустая строка). Структура также определяет хранимое целочисленное свойство с названием numberOfEdits
, которое используется для отслеживания количества модификацией свойства value
. Отслеживание этого изменения реализовано в наблюдателе свойства didSet
значения value
, который инкрементирует значение numberOfEdits
всякий раз при присваивании нового значения свойству value
.
TrackedString
и её свойство value не предоставляют явного модификатора уровня доступа, так что они получают уровень доступа по-умолчанию - внутренний. Однако доступ к numberOfEdits
помечен как private(set)
для указания на то, что геттер свойства всё ещё будет иметь внутренний уровень доступа, но свойство будет задаваемо только изнутри кода, который является частью структуры TrackedString
. Это позволяет TrackedString
изменять значение свойства numberOfEdits
изнутри, но представить его вовне как свойство только-для-чтения.
TrackedString
и измените его строковое значение несколько раз, то Вы увидите, что значения свойства numberOfEdits
обновится для совпадения с количеством изменений:
var stringToEdit = TrackedString()
stringToEdit.value = "This string will be tracked."
stringToEdit.value += " This edit will increment numberOfEdits."
stringToEdit.value += " So will this one."
print("The number of edits is \(stringToEdit.numberOfEdits)")
// Выведет "The number of edits is 3"
И хотя Вы можете запросить текущее значение свойства numberOfEdits
изнутри другого исходного файла, Вы не можете изменить его оттуда. Это ограничение защищает детали реализации TrackedString
от изменения значения отслеживания с собранием удобного доступа к аспектам её функциональности.
TrackedString
, в котором структура определена с явным публичным уровнем доступа. Члены структуры (включая свойство numberOfEdits
) следовательно будут иметь внутренний уровень доступа по-умолчанию. Вы можете сделать геттер свойства numberOfEdits
структуры публичным, а его сеттер приватным, объединив модификаторы public
и private(set)
:
public struct TrackedString {
public private(set) var numberOfEdits = 0
public var value: String = "" {
didSet {
numberOfEdits += 1
}
}
public init() {}
}
public
. Для типа определённого как public
, дефолтный инициализатор определён как внутренний. Если Вы хотите, чтобы можно было инициализировать публично тип с конструктором без аргументов при его использовании в другом модуле, Вы должны явно задать публичный конструктор без аргументов в качестве определение типа.
private extension
) для установки новых уровней доступа по-умолчанию для членов типа, определённых внутри расширения. Это новое значение по-умолчанию может быть перезаписано внутри расширения для отдельных членов типа.
protocol SomeProtocol {
func doSomething()
}
struct SomeStruct {
private var privateVariable = 12
}
extension SomeStruct: SomeProtocol {
func doSomething() {
print(privateVariable)
}
}