a hozzáférés-vezérlés fogalma lehetővé teszi számunkra, hogy korlátozzuk a típusok, funkciók és egyéb deklarációk más kódokkal történő elérését. A Swift öt különböző szintű hozzáférés-vezérlést kínál, és ezek teljes kihasználása kulcsfontosságú lehet olyan programok írásához, amelyek egyértelműen elkülönítik az aggodalmakat és a robusztus struktúrát.

ha bármilyen új típust, tulajdonságot vagy függvényt definiálunk a Swiftben, akkor alapértelmezés szerint a internal hozzáférési szint lesz. Ez azt jelenti, hogy minden más kód látható lesz, amely ugyanabban a modulban él — például egy alkalmazás, egy rendszerbővítmény, egy keretrendszer vagy egy Swift csomag.

például tegyük fel, hogy egy shopping alkalmazást építünk, és hogy meghatároztunk egy PriceCalculator nevű osztályt, amely lehetővé teszi számunkra, hogy kiszámítsuk a termékek tömbjének teljes árát:

mivel jelenleg nem határozunk meg semmilyen explicit hozzáférési szintet, a PriceCalculator osztályunk (és annak calculatePrice módszere) bárhonnan elérhető lesz az alkalmazásunkon belül. Ha azonban meg akarjuk osztani az új osztályunkat más modulokkal (például megvalósíthatjuk egy olyan keretben, amelyet megosztunk a fő alkalmazásunk és egy kiterjesztés között, vagy egy társ Apple Watch app), akkor meg kell csinálnunk public annak érdekében, hogy látható legyen azokban a külső kontextusokban:

a fenti változás azonban nem elég. Bár most már képesek vagyunk megtalálni az osztályunkat azon a modulon kívül, amelyben meg van határozva, nem hozhatunk létre belőle példányokat — mivel az (implicit) inicializálója, mint bármely más kód, alapértelmezés szerint internal. Ennek kijavításához határozzunk meg egy public inicializálót, amelyet üresen hagyunk, mivel nincs benne tényleges munka:

public class PriceCalculator { public init() {} ...}

most már képesek vagyunk megtalálni, inicializálni és hívni a PriceCalculator — t mind a modulon belül, mind azon kívül-fantasztikus. De most mondjuk, hogy alosztályozni is szeretnénk annak módosítása vagy új funkciók hozzáadása érdekében. Bár ez jelenleg lehetséges a saját modulján belül, ez ismét valami, ami megakadályozta rajta kívül.

ennek megváltoztatásához a Swift jelenleg legnyitottabb hozzáférés-vezérlési szintjét kell használnunk, amelyet megfelelően elnevezünk open:

open class PriceCalculator { ...}

a fenti változással most már létrehozhatunk egyéni alosztályokat a PriceCalculator bárhol — amelyek új inicializálókkal, új tulajdonságokkal és új módszerekkel rendelkezhetnek. Itt van, hogyan lehet használni, hogy végre egy DiscountedPriceCalculator, amely lehetővé teszi számunkra, hogy egy adott discount minden ár számítások:

fent egy teljesen új árszámítási módszert határozunk meg, de vitathatatlanul sokkal helyénvalóbb lenne felülbírálni és módosítani a meglévő calculatePrice módszert, amelyet az alaposztályunktól örököltünk. Így nem lenne zavar, hogy melyik módszert hívjuk meg, és a két osztályunkat következetesen tarthatnánk.

ahhoz, hogy ezt megtehessük, ismét meg kell jelölnünk az eredeti nyilatkozatot — ezúttal a calculatePrice módszer deklarációnkat open:

open class PriceCalculator { public init() {} open func calculatePrice(for products: ) -> Int { ... }}

a fentiekkel a helyén most már szabadon felülbírálhatjuk calculatePrice, ahelyett, hogy külön módszert kellene létrehoznunk:

tehát ez internal, public és open — ezeket arra használják, hogy fokozatosan megnyissanak egy nyilatkozatot nyilvános használatra és módosításra. De természetesen a másik irányba is mehetünk, és elrejthetjük a kódunk egyes részeit, hogy felfedezzék és használják. Először megkérdőjelezhetőnek tűnhet, hogy mi ennek az értéke, de valóban segíthet abban, hogy az API — t sokkal szűkebbé és fókuszáltabbá tegyük-ami viszont megkönnyítheti a megértést, a tesztelést és a használatot.

tehát most térjünk át a hozzáférési szint spektrumának másik oldalára, és nézzük meg a legszigorúbb szintet — private. Bármely típus, tulajdonság vagy metódus, amely private – ként van megjelölve, csak a saját típusán belül lesz látható (amely magában foglalja az ugyanazon fájlban meghatározott típus kiterjesztéseit is).

minden, amit egy adott típusú privát megvalósítási részletnek kell tekinteni, vitathatatlanul private – ként kell megjelölni. Például az árkalkulátorunk discount korábbi ingatlanát valójában csak a saját osztályán belül kellett használni — tehát menjünk előre, és tegyük ezt az ingatlant priváttá:

class DiscountedPriceCalculator: PriceCalculator { private let discount: Int ...}

korábbi megvalósításunk továbbra is pontosan ugyanúgy fog működni, mint korábban, mivel a discount teljesen látható marad a DiscountedPriceCalculator osztályunkon belül. Ha azonban kissé ki akarjuk terjeszteni ezt a láthatóságot, hogy az ugyanabban a fájlban meghatározott más típusokat is tartalmazzon, akkor a fileprivate — t kell használnunk-ami pontosan azt teszi, aminek hangzik, a deklarációt privátnak tartja a fájlban, amelyben meg van határozva:

class DiscountedPriceCalculator: PriceCalculator { fileprivate let discount: Int ...}

a fenti változás helyett most már hozzáférhetünk a discount tulajdonsághoz az ugyanabban a fájlban meghatározott kapcsolódó kódból — mint például ez a kiterjesztés a UIAlertController – en, amely lehetővé teszi számunkra, hogy könnyen megjelenítsük az árleírást egy sor termékre egy riasztáson belül:

amikor az ingyenes funkciókról, típusokról és kiterjesztésekről van szó, private és fileprivate pontosan ugyanúgy járnak el. Csak akkor különböznek, ha egy típuson belül definiált deklarációkra alkalmazzák őket.

összefoglalva tehát ez a hozzáférés-vezérlés öt szintje, amelyet a Swift jelenleg kínál:

  • private egy tulajdonságot vagy függvényt magántulajdonban tart a csatoló típusán belül, beleértve az adott típusú kiterjesztéseket, amelyek ugyanabban a fájlban vannak meghatározva. Legfelső szintű típusra, függvényre vagy kiterjesztésre alkalmazva ugyanúgy működik, mint fileprivate.
  • fileprivate a deklarációt láthatóvá teszi a teljes fájlban, amelyben meg van határozva, miközben elrejti az összes többi kód elől.
  • internal az Alapértelmezett hozzáférési szint, és egy deklarációt tesz láthatóvá az egész modulon belül, amelyben meg van határozva.
  • public függvényt, típust, kiterjesztést vagy tulajdonságot tár fel a modulján kívül.
  • open lehetővé teszi egy osztály alosztályozását és egy függvény vagy tulajdonság felülbírálását a modulon kívül.

általánosságban elmondható, hogy gyakran a legjobb, ha egy adott deklaráció gyakorlatilag a legszigorúbb hozzáférési szinttel indul, majd szükség esetén később nyitja meg a dolgokat. Így korlátozzuk a különféle típusaink és funkcióink közötti interakció lehetőségeit, ami először rossz dolognak tűnhet, de gyakran valóban elengedhetetlen a karbantartható és jól strukturált rendszerek felépítéséhez.

Köszönöm az olvasást! 6885

(Megjegyzendő, hogy ez a cikk nem tartalmaz mutáció-specifikus hozzáférési módosítókat, például private(set). Ezeket a jövőben egy másik Alapcikk fogja lefedni.)

támogassa a Swift by Sundell-t a szponzor ellenőrzésével:

Instabug: Sokkal gyorsabban oldhatja meg a hibákat, összeomlásokat és egyéb problémákat a részletes veremnyomok, hálózati naplók és UI események segítségével, amelyeket az Instabug automatikusan csatol az egyes hibajelentésekhez. Mind az én, mind az iOS fejlesztői csapatok ezrei használják szerte a világon. Próbálja ki ingyen, és integrálja csak egy sor kódot.

Vélemény, hozzászólás?

Az e-mail-címet nem tesszük közzé.