2016-02-17 27 views
17

Innanzitutto, capisco la differenza tra valore e tipi di riferimento: questa non è la domanda. Sto riscrivendo parte del mio codice in Swift e ho deciso di ridefinire alcune classi. Pertanto, ho pensato di vedere se alcune delle classi hanno senso come strutture.Swift Struct vs Class: qual è la dimensione dello stack consentita? e refactoring di una classe a una struct

Memoria: Ho alcune classi di modelli che contengono array molto grandi, che sono in costante aumento di dimensioni (dimensioni finali sconosciute) e potrebbero esistere per ore. Innanzitutto, ci sono delle linee guida su una dimensione suggerita o assoluta per una struttura, dal momento che vive in pila?

Refactoring Utilizzo: Dato che sto rifattorizzando quello che adesso è un casino con troppa dipendenza, mi chiedo come potrei migliorarlo. Le viste e i controller di vista sono per lo più facili, è il mio modello e quello che fa, mi ha sempre lasciato desiderare esempi migliori da seguire.

WorkerManager: Singleton che contiene uno o due Worker s alla volta. Uno registrerà sempre nuovi dati da un sensore e l'altro controllerà i dati memorizzati. I controller della vista ottengono il riferimento Worker da WorkerManager e chiedono il Worker per i dati da visualizzare.

Worker: fa tutto su una coda, per evitare problemi di accesso alla memoria (i puntatori degli array C cambiano continuamente man mano che crescono). Ascolto: L'ascolto Worker ascolta i nuovi dati, li invia a un oggetto Processor (che ha creato) che pulisce i dati e li archivia in array C detenuti dallo Worker. Quindi, se sono disponibili dati validi,indica allo Analyzer (anch'esso di proprietà del lavoratore) di analizzare i dati e di memorizzarli in altri array C da alimentare alle viste. Sia lo Processor sia lo Analyzer hanno bisogno dello stato per sapere cosa è successo in passato e cosa elaborare e analizzare successivamente. I dati puri grezzi sono memorizzati in un oggetto separato NS Record. Il revisore prende uno Record e utilizza i dati puri grezzi per ricreare tutti i dati analizzati in modo che possano essere rivisti. (i dati analizzati sono enormi e non voglio memorizzarli su disco)

Ora, la mia seconda domanda è, potrebbe/dovrebbe Processor e Analyzer essere sostituita con le strutture? O forse protocolli per lo Worker? Non sono realmente "oggetti" nel senso normale, solo gruppi convenienti di metodi correlati e lo stato necessario. E dal momento che il codice è quasi un migliaio di righe per ciascuno, e non voglio mettere tutto in una classe, o anche lo stesso file.

Non ho proprio un buon senso di come rimuovere tutto il mio stato, utilizzare le funzioni pure per tutte le complesse operazioni matematiche eseguite sugli array e dove metterle.

+0

Forse dovresti postare qualche codice di esempio – dispute

+0

Penso che la parte stack/heap della domanda sia piuttosto semplice. L'altra parte è più di "qual è la migliore pratica quando hai un oggetto che è grande e in costante crescita". Poiché queste classi hanno molte parti funzionanti, è troppo codice da pubblicare. –

+0

Sono un po 'confuso dalla tua domanda e commento; la tua domanda legge "... size for a struct, dal momento che vive in pila?", ma il tuo commento dice "... la parte stack/heap della domanda è piuttosto semplice". Quando dici che è semplice, vuol dire che sei chiaro su come allocare la memoria per le strutture dall'heap invece di dichiararle semplicemente sullo stack di chiamate e avere il tempo di esecuzione gestire la gestione della memoria per te? – fullofsquirrels

risposta

1

Mentre la struttura vive nello stack, i dati dell'array sono presenti nell'heap in modo che la matrice possa crescere in dimensione dinamicamente. Pertanto, anche se si dispone di un array con milioni di elementi e lo si passa da qualche parte, nessuno degli elementi viene copiato finché non si cambia il nuovo array a causa dell'implementazione copy-on-write. Questo è descritto in dettaglio in 2015 WWDC Session 414.

Per quanto riguarda la seconda domanda, penso che 2015 WWDC Session 414 abbia di nuovo la risposta.Il controllo di base che Apple engineers recommend per i tipi di valore sono:

utilizzare un tipo di valore quando:

  • Confrontando i dati di istanza con == senso
  • Volete copie di avere stato indipendente
  • Il i dati verranno utilizzati nel codice attraverso più thread

Utilizzare un tipo di riferimento (ad es. utilizzare una classe) quando:

  • Confrontando identità un'istanza con === senso
  • si desidera creare condivisa, dello stato mutabile

Quindi, da quello che hai descritto, penso che tipi di riferimento si adattano Processor e Analyzer molto meglio. Non sembra che le copie di Processor e Analyzer siano oggetti validi se non hai creato nuovi Producer se Analyzer s esplicitamente. Non vuoi che le modifiche a questi oggetti siano condivise?

+0

Ho visto Session 414 e ho appena controllato la trascrizione, no dove parla dello stack. E i soli riferimenti all'heap sono quando il presentatore parla di oggetti, non di strutture. –

+0

E il problema con il valore v. Suggerimento di riferimento, è che questi dati sono a cavallo tra entrambi i domini. I dati vengono utilizzati su più thread e devono essere modificabili. Tuttavia, non vi è alcun senso delle copie, perché solo una esiste alla volta (o due). Se stavo facendo centinaia di copie da utilizzare su thread sarebbe orribilmente inefficiente. –