swift singleton swift2

¿Alguna razón por la que no se usa usa una "variable" singleton en Swift?



swift2 (3)

Funcionalmente, estos son muy similares, pero recomendaría usar la sintaxis Model.shared porque eso deja absolutamente claro, donde sea que lo use, que está tratando con un singleton, mientras que si solo tiene ese model global flotando por ahí , no está claro con qué estás tratando.

Además, con los globales (especialmente con un nombre simple como "modelo"), corre el riesgo de tener una clase futura que tenga variables con nombres similares y accidentalmente haga referencia a la incorrecta.

Para una discusión sobre las consideraciones generales con respecto a los globales v singletons v otros patrones, vea Variables globales son malas que, a pesar del título bastante destacado, presenta una discusión sobria, tiene algunos enlaces interesantes y presenta alternativas.

Por cierto, para tus "amigos del TOC" (dentro de los cuales supongo que debo contarme a mí mismo, porque creo que es la mejor práctica), no solo declararías init como private , sino que probablemente declararías que toda la clase es final , para evitar subclases (en ese momento se vuelve ambiguo a lo que se shared referencias).

Para septiembre de 2015, así es exactamente cómo se hace un singleton en Swift:

public class Model { static let shared = Model() // ( for ocd friends ... private init() {} ) func test()->Double { return 3.33 } }

entonces en otro lado ...

// file ViewController.swift, say import UIKit class ViewController:UIViewController { override func viewDidLoad() { super.viewDidLoad() print("view controller loaded!") print("singleton test! /( Model.shared.test() )") } }

No hay problema.

Sin embargo. Añado esta cosita ...

public let model = Model.shared public class Model { static let shared = Model() func test()->Double { return 3.33 } }

entonces, simplemente puede hacer lo siguiente en todo el proyecto:

class ViewController:UIViewController { override func viewDidLoad() { super.viewDidLoad() print("view controller loaded!") print("singleton test! /( model.test() )") } }

Idioma convencional:

Model.shared.blah () ... ves esto en todas partes en la base del código

"mi" idioma:

model.blah () ... ves esto en todas partes en la base del código

Entonces, esto hace que todo se vea bonito:

(En su proyecto, esas "variables singleton" serían cosas como scores. , networking. , heuristics. o cualquier otro caso en su proyecto).

Esto, entonces, es un modismo "macro".

El único propósito es el aspecto del código.

Simplificando las apariencias de ImportantSystem.SharedImportantSystem hasta importantSystem. a lo largo del proyecto.

¿Alguien puede ver algún problema con este idioma?

Los problemas pueden ser técnicos, estilísticos o de cualquier otra categoría, siempre que sean muy profundos.


Hay algunas cosas a tener en cuenta al usar este enfoque:

La variable global

Una variable global en sí misma no es gran cosa, pero si tiene bastantes variables globales, puede tener problemas con el autocompletado, ya que siempre sugerirá estas variables globales.

Otro problema con las variables globales es que podría tener otro módulo en su aplicación (escrito por usted o de otra manera) que defina la misma variable global. Esto causa problemas al usar estos 2 módulos juntos. Esto se puede resolver mediante el uso de un prefijo, como las iniciales de su aplicación.

El uso de variables globales generalmente se considera una mala práctica .

El patrón singleton

Un singleton es útil cuando se trabaja con un controlador o un repositorio. Una vez se creó, y crea todo de lo que depende. Solo puede haber un controlador y solo abre una conexión a la base de datos. Esto evita muchos problemas al trabajar con recursos o variables a los que se debe acceder desde toda la aplicación.

Sin embargo, hay inconvenientes, como la capacidad de prueba. Cuando una clase usa un singleton, el comportamiento de esa clase ahora se ve afectado por el comportamiento de los singletons.

Otro posible problema es la seguridad del hilo. Al acceder a un singleton desde diferentes subprocesos sin bloqueo, pueden surgir problemas que son difíciles de depurar.

Resumen

Debe tener cuidado al definir variables globales y trabajar con singletons. Con la atención adecuada, no deberían surgir muchos problemas.


No puedo ver una sola desventaja de este enfoque:

  • Puede usar diferentes variables para diferentes partes del programa (-> Sin espacio de nombres abarrotado si no le gusta esto, supongo)
  • Es corto, bonito, fácil de usar y tiene sentido cuando lo lees. Model.shared.test() realmente no tiene sentido si lo piensas, solo quieres llamar a test, ¿por qué tendría que llamar a shared cuando solo necesito una función?
  • Utiliza el espacio de nombres global lento de Swift: la clase se asigna e inicializa cuando la usa la primera vez; si nunca lo usas, ni siquiera se asigna / inicia.

En general, dejando de lado el idioma exacto en discusión, con respecto al uso de singletons:

  • Recuerde que, por supuesto, en lugar de usar static var shared = Model() como una especie de macro para un singleton, como se sugiere en esta Q, puede definir let model = Model() que simplemente crea un global normal (no relacionado con Singletons).
  • Con los singletons de Swift, se ha discutido que posiblemente quieras agregar un private init() {} a tu clase, para que solo se inicialice una vez (teniendo en cuenta que todavía se puede llamar a init en el mismo archivo).
  • Por supuesto, en general, cuando se considera el uso de un singleton, si realmente no necesita un estado y la instancia de clase en sí, simplemente puede usar funciones / propiedades estáticas. Es un error común usar un singleton (por ejemplo, funciones "de cálculo") donde todo lo que se necesita es un método estático.