Swift Structural vs Class: ¿cuál es el tamaño de stack permitido? y refactorizar una class a una estructura

Primero, entiendo la diferencia entre el valor y los types de reference; esta no es esa pregunta. Estoy reescribiendo parte de mi código en Swift, y decidí también refactorizar algunas de las classs. Por lo tanto, pensé que vería si algunas de las classs tienen sentido como estructuras.

Memoria: tengo algunas classs de models que contienen matrices muy grandes, que están creciendo constantemente en tamaño (tamaño final desconocido) y podrían existir durante horas. Primero, ¿hay alguna guía sobre un tamaño sugerido o absoluto para una estructura, ya que vive en la stack?

Uso de Refactorización: Como estoy refactorizando lo que ahora es un desastre con demasiada dependencia, me pregunto cómo podría mejorar eso. Las vistas y los controlleres de vista son principalmente fáciles, es mi model, y lo que hace, eso siempre me deja deseando mejores ejemplos a seguir.

WorkerManager : Singleton que contiene uno o dos Worker a la vez. Uno siempre estará grabando nuevos datos de un sensor, y el otro estaría revisando los datos almacenados. Los controlleres de vista obtienen la reference de Worker del WorkerManager y le piden al Worker que muestre los datos.

Worker : hace todo en una queue, para evitar problemas de acceso a la memory (los pointers C array cambian constantemente a medida que crecen). Listening: El Worker escucha escucha nuevos datos, los envía a un object Processor (que creó) que limpia los datos y los almacena en C arrays en poder del Worker . Luego, si hay datos válidos, el Worker le dice al Analyzer (también propiedad del trabajador) que analice los datos y los almacene en otras matrices C para alimentarlas. Tanto el Processor como el Analyzer necesitan saber qué pasó en el pasado y qué procesar y analizar a continuación. Los datos en bruto puros se almacenan en un object Record NSManaged separado. El revisor toma un Record y usa los datos puros sin procesar para recrear todos los datos analizados para que puedan revisarse. (los datos analizados son masivos y no quiero almacenarlo en el disco)

Ahora, mi segunda pregunta es, ¿podría / debería Processor y el Analyzer con estructuras? O tal vez protocolos para el Worker ? No son realmente "objects" en el sentido normal, solo grupos convenientes de methods relacionados y el estado necesario. Y ya que el código es casi mil líneas para cada uno, y no quiero ponerlo todo en una class, o incluso el mismo file.

Simplemente no tengo una buena idea de cómo eliminar todo mi estado, uso funciones puras para todas las operaciones matemáticas complejas que se realizan en las matrices y dónde colocarlas.

Si bien la estructura en sí misma vive en la stack, los datos de la matriz permanecen en el montón para que la matriz pueda crecer en tamaño dinámicamente. Entonces, incluso si tiene una matriz con millones de elementos y la pasa a alguna parte, ninguno de los elementos se copyrá hasta que cambie la nueva matriz debido a la implementación de copy en escritura . Esto se describe en detalle en la Sesión 414 de WWDC 2015 .

En cuanto a la segunda pregunta, creo que la Sesión 414 de WWDC 2015 nuevamente tiene la respuesta. La comprobación básica que los ingenieros de Apple recomiendan para los types de valor son:

Use un tipo de valor cuando:

  • Comparar los datos de instancia con == tiene sentido
  • Desea que las copys tengan un estado independiente
  • Los datos se usarán en código a través de varios subprocesss.

Use un tipo de reference (por ejemplo, use una class) cuando:

  • Comparar la identidad de la instancia con === tiene sentido
  • Desea crear un estado mutable compartido

Entonces, por lo que has descrito, creo que los types de reference se ajustan mucho mejor al Processor y al Analyzer . No parece que las copys de Processor y Analyzer sean objects válidos si no ha creado nuevos Producer y Analyzer explícitamente. ¿No querrías compartir los cambios en estos objects?