Respuestas:
fileprivate
ahora es lo que private
solía ser en versiones anteriores de Swift: accesible desde el mismo archivo fuente. Una declaración marcada como private
ahora solo se puede acceder dentro del ámbito léxico en el que se declara. Por private
lo tanto, es más restrictiva que fileprivate
.
A partir de Swift 4, las declaraciones privadas dentro de un tipo son accesibles para extensiones del mismo tipo si la extensión se define en el mismo archivo fuente.
Ejemplo (todo en un archivo fuente):
class A {
private func foo() {}
fileprivate func bar() {}
func baz() {
foo()
bar()
}
}
extension A {
func test() {
foo() // Swift 3: error: use of unresolved identifier 'foo'
// Swift 4: no error because extension is in same source file
bar()
}
}
let a = A()
a.foo() // error: 'foo' is inaccessible due to 'private' protection level
a.bar()
foo
Solo se puede acceder al método privado dentro del alcance de la class A { ... }
definición. Ni siquiera es accesible desde una extensión al tipo (en Swift 3, consulte la segunda nota a continuación para ver los cambios en Swift 4).
Se bar
puede acceder al método privado de archivo desde el mismo archivo fuente.
Notas:
La propuesta SE-0159 - Arreglar niveles de acceso privado sugirió volver a la semántica de Swift 2 en Swift 4. Después de una discusión larga y controvertida sobre la lista de correo de evolución rápida, la propuesta fue rechazada .
La propuesta SE-0169 - Mejorar la interacción entre declaraciones y extensiones privadas sugiere hacer que las private
declaraciones dentro de un tipo sean accesibles para extensiones del mismo tipo si la extensión se define en el mismo archivo fuente.
Esta propuesta fue aceptada e implementada en Swift 4.
foo()
llamada.
Solo dibujo un diagrama sobre privado , privado de archivos , abierto y público
Espero que pueda ayudarlo rápidamente, para la descripción del texto, consulte la respuesta de Martin R
[Actualizar Swift 4]
fileprivate
no está vinculado a la extensión sino al archivo (escribir una extensión de clase A en otro archivo no permitirá el uso de fileprivate
miembros)
public
no le permitirá heredar, por lo tanto, la tercera imagen es incorrecta. Además, siempre puede poner una extensión a cualquier clase si puede verla. Explicar la visibilidad en las extensiones no es una muy buena idea entonces.
Una regla práctica es que use private para variables, constantes, estructuras internas y clases que se usan solo dentro de la declaración de su clase / estructura. Utiliza fileprivate para cosas que se usan dentro de sus extensiones dentro del mismo archivo que su clase / estructura pero fuera de sus llaves definidas (es decir, su alcance léxico).
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
}
}
En Swift 4.0, Private ahora es accesible en extensión pero dentro del mismo archivo. Si declara / define la extensión en otro archivo, entonces su variable privada no será accesible para su extensión **
File Private
File-private access restringe el uso de una entidad a su propio archivo fuente de definición. Use el acceso privado a archivos para ocultar los detalles de implementación de una funcionalidad específica cuando esos detalles se usan dentro de un archivo completo.
Sintaxis: fileprivate <var type> <variable name>
Ejemplo: fileprivate class SomeFilePrivateClass {}
Privado
El acceso privado restringe el uso de una entidad a la declaración adjunta y a las extensiones de esa declaración que están en el mismo archivo . Use el acceso privado para ocultar los detalles de implementación de una pieza específica de funcionalidad cuando esos detalles se usan solo dentro de una sola declaración.
Sintaxis: private <var type> <variable name>
Ejemplo: private class SomePrivateClass {}
Aquí hay más detalles sobre todos los niveles de acceso: Swift - Niveles de acceso
Mire estas imágenes:
Archivo: ViewController.swift
Aquí la extensión y el controlador de vista están en el mismo archivo, por lo tanto, la variable privada testPrivateAccessLevel
es accesible en extensión
Archivo: TestFile.swift
Aquí la extensión y el controlador de vista están en archivos diferentes, por lo tanto, la variable privada testPrivateAccessLevel
no es accesible en extensión.
Aquí la clase ViewController2
es una subclase de ViewController
y ambos están en el mismo archivo. Aquí testPrivateAccessLevel
no se puede acceder a la variable privada en la Subclase, pero se puede acceder a fileprivate en la subclase.
Aunque la respuesta de @ MartinR y @ StephenChen es perfecta, Swift 4 cambia un poco las cosas.
Privado ahora se considera privado a una clase en la que se declara y también a sus extensiones.
FilePrivate se considera privado en ese archivo, ya sea una clase en la que se define la variable, su extensión o cualquier otra clase definida en ese mismo archivo.
Actualizado para Swift 5
Privado vs FilePrivate
Para mayor claridad, pegue el fragmento de código en 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
}
}
Nota : Fuera del archivo Swift, no se puede acceder a los archivos privados ni a los privados.
filePrivate : el nivel de control de acceso está dentro del archivo.
caso 1 : si creamos una extensión con el mismo archivo de clase e intentamos acceder a la función fileprivate o la propiedad fileprivate en su extensión - acceso permitido
caso 2 : si creamos una extensión de clase en un archivo nuevo - Y ahora intentamos acceder a la función fileprivate o fileprivate propiedad - acceso no permitido
privado : el nivel de control de acceso tiene un alcance léxico
caso 1 : Si la propiedad o función se declara como privada en la clase, entonces el alcance es por defecto la clase. caso 2 : si la instancia privada se declara con el cuerpo de la función, el alcance de la instancia se limita al cuerpo de la función.
En el siguiente ejemplo, las construcciones del lenguaje modificadas por private
y fileprivate
parecen comportarse de manera idéntica:
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))
Esto es de acuerdo con la intuición, supongo. Pero, ¿hay alguna excepción?
Saludos cordiales.
Esta es la explicación de swift 4. Para swift 3, la diferencia es el privado. No se puede acceder a swift 3 private por su extensión, solo la clase A puede acceder.
Después de swift 4, fileprivate se vuelve un poco redundante, porque la persona normalmente no definirá la subclase en el mismo archivo. Privado debería ser suficiente para la mayoría de los casos.
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()
}
}
Me gusta esto porque es súper simple para ivars.
Intente cambiar fileprivate a privado (y viceversa) y vea qué sucede en la compilación ...
private
enfileprivate
. Sin embargo, si tiene el lujo de hacerlo a mano, a menudo puede beneficiarse de irseprivate
comoprivate
... si se compila, todo bien.