language swift swift3 private access-control access-specifier

language - swift variables



¿Cuál es un buen ejemplo para diferenciar entre fileprivate y private en Swift3? (10)

Este article ha sido útil para comprender los nuevos especificadores de acceso en Swift 3 . También da algunos ejemplos de diferentes usos de fileprivate y private .

Mi pregunta es: ¿no es usar fileprivate en una función que se va a usar solo en este archivo lo mismo que usar private ?


Acabo de dibujar 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]


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.


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 **

Archivo privado
El acceso privado a archivos 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 . Utilice 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

Mira 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 diferentes archivos, 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í la variable privada testPrivateAccessLevel no está accesible en la Subclase, pero fileprivate está accesible en la subclase.


En el siguiente ejemplo, las construcciones de 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 según 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.


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 } }


fileprivate es ahora lo que era private en versiones anteriores de Swift: accesible desde el mismo archivo fuente. Ahora solo se puede acceder a una declaración marcada como private dentro del ámbito léxico en el que se declara. Por lo tanto, private es más restrictivo 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()

  • Solo se puede acceder al método foo privado dentro del alcance de la definición de class A { ... } . 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 puede acceder al método de bar archivo privado desde el mismo archivo fuente.

Notas:

  1. La propuesta SE-0159 - Arreglar los 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 rejected .

  2. La propuesta SE-0169 - Mejorar la interacción entre declaraciones y extensiones privadas sugiere hacer que private declaraciones private 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.


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 privada de archivo o la propiedad privada de archivo, el acceso no está 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, 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.


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 ...