¿Cuál es un buen ejemplo para diferenciar entre privado de archivos y privado en Swift3?

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

Mi pregunta es: ¿no está utilizando fileprivate en una función que se va a usar solo en este archivo y que usa private ?

fileprivate ahora es lo que solía ser en versiones anteriores de Swift: accesible desde el mismo archivo fuente. Ahora solo se puede acceder a una statement marcada como private dentro del scope léxico en el que se declara. Por lo tanto, private fileprivate es más restrictiva que la fileprivate de 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() 
  • El método foo privado es accesible solo dentro del scope de la definición de class A { ... } . Ni siquiera se puede acceder desde una extensión al tipo (en Swift 3, consulte la segunda nota a continuación para conocer los cambios en Swift 4).

  • El método de bar archivos privados es accesible desde el mismo archivo fuente.

Notas:

  1. La propuesta SE-0159 – Fijar 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 .

  2. La propuesta SE-0169 – Mejorar la interacción entre declaraciones privadas y extensiones sugiere hacer declaraciones private dentro de un tipo accesible 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.

Solo dibujé un diagtwig sobre private , fileprivate , 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]

enter image description here

Una regla empírica práctica es que utiliza private para variables, constantes, estructuras internas y clases que se usan solo dentro de la statement de su clase / estructura. Utiliza fileprivate para las cosas que se usan dentro de tus extensiones dentro del mismo archivo que tu clase / struct pero fuera de sus llaves de definición (es decir, su scope 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 } } 

Aunque @ MartinR y @ StephenChen son perfectos, Swift 4 cambia las cosas un poco.

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

En Swift 4.0, ahora se puede acceder a Private en la extensión pero dentro del mismo archivo. Si declara / define la extensión en otro archivo, entonces su extensión no podrá acceder a su variable privada **

Archivo privado
El acceso de archivo privado restringe el uso de una entidad a su propio archivo fuente de definición. Utilice el acceso de archivo privado para ocultar los detalles de implementación de una pieza específica de funcionalidad cuando esos detalles se usan dentro de un archivo completo.
Sintaxis: fileprivate
Ejemplo: fileprivate class SomeFilePrivateClass {}

Privado
El acceso privado restringe el uso de una entidad a la statement adjunta, y a las extensiones de esa statement 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 statement.
Sintaxis: private
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í los controladores de extensión y vista están en el mismo archivo, por testPrivateAccessLevel se puede acceder a la variable privada testPrivateAccessLevel en extensión

enter image description here

Archivo: TestFile.swift
Aquí la extensión y el controlador de vista se encuentran en diferentes archivos, por lo tanto, no se puede acceder a la variable privada testPrivateAccessLevel en la extensión.

enter image description here

enter image description here

Aquí la clase ViewController2 es una subclase de ViewController y ambas están en el mismo archivo. Aquí no se puede acceder a la variable privada testPrivateAccessLevel en Subclass, pero se puede acceder a private de archivo en la subclase.

enter image description here

 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 muy simple para ivars.

Intenta cambiar fileprivate a privado (y viceversa) y mira qué pasa en la comstackción …

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 a 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 de archivos privados o propiedad privada de archivos – acceso no permitido

privado – el nivel de control de acceso está dentro del scope léxico

caso 1 : si la propiedad o la función se declara como privada en clase, entonces el scope es por defecto la clase. caso 2 : si se declara una instancia privada en el cuerpo de la función, entonces el scope de la instancia está limitado al cuerpo de la función.