fileprivate
теперь то, что private
было в более ранних выпусках Swift: доступно из того же исходного файла. К объявлению, помеченному как, private
теперь можно получить доступ только в пределах лексической области видимости, в которой оно объявлено. private
Это более ограничительно, чем fileprivate
.
Начиная с Swift 4, частные объявления внутри типа доступны для расширений того же типа, если расширение определено в том же исходном файле.
Пример (все в одном исходном файле):
class A {
private func foo() {}
fileprivate func bar() {}
func baz() {
foo()
bar()
}
}
extension A {
func test() {
foo()
bar()
}
}
let a = A()
a.foo()
a.bar()
Частный foo
метод доступен только в рамках class A { ... }
определения. Он даже недоступен из расширения к типу (в Swift 3 см. Вторую заметку ниже об изменениях в Swift 4).
Метод file-private bar
доступен из того же исходного файла.
Примечания:
В предложении SE-0159 - Fix Private Access Levels предлагалось вернуться к семантике Swift 2 в Swift 4. После долгого и противоречивого обсуждения списка рассылки быстрой эволюции предложение было отклонено .
Предложение SE-0169 - Улучшение взаимодействия между частными объявлениями и расширениями предлагает сделать private
объявления внутри типа доступными для расширений того же типа, если расширение определено в том же исходном файле.
Это предложение было принято и реализовано в Swift 4.
private
вfileprivate
. Однако, если у вас есть возможность сделать это вручную, вы часто можете получить выгоду, оставивprivate
asprivate
... если он компилируется, все хорошо.foo()
звонку.Я просто рисую диаграмму о частных , файловых , открытых и общедоступных
Надеюсь, это поможет вам быстро, текстовое описание см. В ответе Мартина Р.
[Обновить Swift 4, 5]
источник
fileprivate
fileprivate
public
вы не сможете наследовать, поэтому третье изображение неверно. Кроме того, вы всегда можете добавить расширение к любому классу, если видите его. Объяснять видимость расширений - не очень хорошая идея.Практическое эмпирическое правило заключается в том, что вы используете private для переменных, констант, внутренних структур и классов, которые используются только внутри объявления вашего класса / структуры. Вы используете fileprivate для вещей, которые используются внутри ваших расширений в том же файле, что и ваш класс / структура, но за пределами их определяющих фигурных скобок (т. Е. Их лексической области видимости).
class ViewController: UIViewController { @IBOutlet var tableView: UITableView! //This is not used outside of class Viewcontroller private var titleText = "Demo" //This gets used in the extension fileprivate var list = [String]() override func viewDidLoad() { navigationItem.title = titleText } } extension ViewController: UITableViewDataSource { func numberOfSections(in tableView: UITableView) -> Int { return list.count } }
источник
В Swift 4.0 Private теперь доступен в расширении, но в том же файле. Если вы объявите / определите расширение в другом файле, ваша личная переменная не будет доступна для вашего расширения **
Приватный
доступ к файлу Приватный доступ к файлу ограничивает использование объекта его собственным определяющим исходным файлом. Используйте частный доступ к файлу, чтобы скрыть детали реализации определенной части функциональности, когда эти детали используются во всем файле.
Синтаксис:
fileprivate <var type> <variable name>
Пример:
fileprivate class SomeFilePrivateClass {}
Частный
частный доступ ограничивает использование сущности включающим объявлением и расширениями этого объявления, которые находятся в том же файле . Используйте частный доступ, чтобы скрыть детали реализации определенной части функциональности, когда эти детали используются только в одном объявлении.
Синтаксис:
private <var type> <variable name>
Пример:
private class SomePrivateClass {}
Вот более подробная информация обо всех уровнях доступа: Swift - Уровни доступа
Посмотрите на эти изображения:
File: ViewController.swift
Здесь расширение и контроллер представления находятся в одном файле, поэтому частная переменная
testPrivateAccessLevel
доступна в расширенииФайл: TestFile.swift
Здесь расширение и контроллер представления находятся в разных файлах, поэтому закрытая переменная
testPrivateAccessLevel
недоступна в расширении.Здесь класс
ViewController2
является подклассом,ViewController
и оба они находятся в одном файле. Здесь приватная переменнаяtestPrivateAccessLevel
недоступна в подклассе, но файловая приватная доступна в подклассе.источник
Обновлено для Swift 5
Частный против FilePrivate
Для большей наглядности вставьте фрагмент кода в Playground
class Sum1 { let a: Int! let b: Int! private var result: Int? fileprivate var resultt: Int? init(a : Int, b: Int) { self.a = a self.b = b } func sum(){ result = a + b print(result as! Int) } } let aObj = Sum1.init(a: 10, b: 20) aObj.sum() aObj.resultt //File Private Accessible as inside same swift file aObj.result //Private varaible will not be accessible outside its definition except extensions extension Sum1{ func testing() { // Both private and fileprivate accessible in extensions print(result) print(resultt) } } //If SUM2 class is created in same file as Sum1 --- class Sum2{ func test(){ let aSum1 = Sum1.init(a: 2, b: 2) // Only file private accessible aSum1.resultt } }
Примечание . Вне файла Swift недоступны как частные, так и частные файлы.
источник
Хотя ответы @ MartinR и @ StephenChen идеальны, Swift 4 немного меняет ситуацию.
Private теперь считается закрытым для класса, в котором он объявлен, а также для его расширений.
FilePrivate считается закрытым в этом файле, будь то класс, в котором определена переменная, его расширение или любые другие классы, определенные в том же файле.
источник
filePrivate - уровень контроля доступа находится внутри файла.
Случай 1 : Если мы создаем расширение с тем же файлом класса и пытаемся получить доступ к функции fileprivate или свойству fileprivate в его расширении - доступ разрешен,
случай 2 : Если мы создаем расширение класса в новом файле - А теперь попробуйте получить доступ к функции fileprivate или fileprivate свойство - доступ запрещен
private - уровень контроля доступа находится в лексической области
случай 1 : Если свойство или функция объявлены в классе как частные, то по умолчанию область видимости - это класс. случай 2 : если частный экземпляр объявлен в теле функции - тогда объем экземпляра ограничен телом функции.
источник
Это объяснение Swift 4. Для swift 3 разница в частном. Swift 3 private не может быть доступен его расширению, только сам класс A может получить доступ.
После swift 4 fileprivate становится немного избыточным, потому что обычно человек не определяет подкласс в том же файле. Частного должно быть достаточно для большинства случаев.
источник
В следующем примере языковые конструкции, измененные
private
и,fileprivate
похоже, ведут себя идентично:fileprivate func fact(_ n: Int) -> Int { if (n == 0) { return 1 } else { return n * fact(n - 1) } } private func gauss(_ n: Int) -> Int { if (n == 0) { return 0 } else { return n + gauss(n - 1) } } print(fact(0)) print(fact(5)) print(fact(3)) print(gauss(10)) print(gauss(9))
Полагаю, это интуитивно. Но есть ли исключения?
С наилучшими пожеланиями.
источник
class Privacy { fileprivate(set) var pu:Int { get { return self.pr } set { self.pr = newValue } } private var pr:Int = 0 fileprivate var fp:Int = 0 func ex() { print("\(self.pu) == \(self.pr) and not \(self.fp)") } } extension Privacy { func ex2() { self.pu = 5 self.ex() } }
Мне это нравится, потому что для ivars это очень просто.
Попробуйте изменить fileprivate на private (и наоборот) и посмотрите, что произойдет при компиляции ...
источник