ProgrammazioneSviluppatore iOS

Spiega il principio di accesso a private/protected/internal/public/open in Swift. Quando è meglio utilizzare ciascuno dei modificatori e quali errori si possono incontrare in un progetto reale?

Supera i colloqui con l'assistente IA Hintsage

Risposta

In Swift ci sono cinque livelli di accesso ai membri dei tipi (proprietà, metodi, ecc.) e ai tipi stessi:

  • open — massimo grado di pubblicità. Può essere ereditato e sovrascritto anche al di fuori del modulo.
  • public — accessibile al di fuori del modulo, ma non può essere sovrascritto/ereditato.
  • internal (di default) — accessibile all'interno del modulo.
  • fileprivate — accessibile solo all'interno del file.
  • private — accessibile solo nell'ambito della dichiarazione (l'estensione è anch'essa in questo scope).

Regole di utilizzo:

  • Utilizzare private per la logica che non dovrebbe essere visibile all'esterno della dichiarazione.
  • fileprivate — se è necessario scambiare dati all'interno di un file (ad esempio, tra due estensioni correlate).
  • internal — default per tutto ciò che è pubblico nel modulo.
  • public/open — per API utilizzate da altri moduli/framework.

Esempio:

open class MyOpenClass {} public class MyPublicClass {} internal class InternalClass {} fileprivate class FilePrivateClass {} private class PrivateClass {}

Domanda insidiosa

Qual è la differenza tra open e public nella descrizione di una classe? Perché non tutte le classi pubbliche sono disponibili per l'ereditarietà?

Risposta: open contrassegna la classe/metodo come disponibile per l'override e l'ereditarietà al di fuori del proprio modulo. public apre solo l'accesso all'uso, ma non consente di creare sottoclassi al di fuori del modulo. Da un lato, questo protegge l'implementazione da modifiche indesiderate, dall'altro — apre solo i punti di estensione necessari.

public class PublicClass {} open class OpenClass {} // In un altro modulo: class InheritFromOpen: OpenClass {} // OK class InheritFromPublic: PublicClass {} // Errore!

Esempi di errori reali dovuti alla mancanza di conoscenza delle sfumature dell'argomento


Storia

In una libreria comune, una classe era contrassegnata come pubblica e un progetto esterno ha tentato di estenderla sovrascrivendo metodi. Il progetto non si compila a causa di una comprensione errata della differenza tra pubblico e open — è costato alla squadra una settimana extra per rivedere l'interfaccia.


Storia

All'interno di un file si è tentato di accedere a una proprietà private da un'estensione — ma la proprietà era stata dichiarata non come fileprivate, ma come private. Questo ha portato a un errore di compilazione, che è stato notato solo nella build di integrazione.


Storia

In un'app con più framework, tutti i tipi erano contrassegnati come internal (di default). Quando è stato necessario utilizzare i tipi tra i moduli, l'interfaccia non era accessibile — è stato necessario riscrivere decine di dichiarazioni su public, il che ha richiesto tempo e test aggiuntivi.