Strah se počasi vklopi, ko sem ugotovil, da mi začne zmanjkovati teh fotografij

Swift + inicializacija z zaprtji

Zapirala F.T.W.

Hitro opombo - vse moje prihodnje objave bodo objavljene na mojem namenskem spletnem mestu in ta publikacija se ne posodablja več. Hvala za branje!

Začenjam resnično izkopati celoten inicializacijski ples v Swiftu. O tem sem že pisal. Pisal sem o tem, zakaj sploh deluje tako, kot to počne. O tem sem govoril. O tem sem veliko bral. Ampak hej, vrnem se k še enemu dejanju glede te zadeve.

Od številnih lepih in raznolikih načinov lahko v Swiftu nekaj inicializiramo - uporaba zaprtja običajno ni prikazana kot metoda za to. Toda na žalost lahko koda kotla za platformo ™ init () postane veliko manj boleča in nekoliko bolj obvladljiva.

Za programske uporabniške vmesnike razvite zunaj - te za vas !

UIKit == UIHugeSetupCode ()

Poglejte, ni kriv UIKits Komponente, s katerimi mora uporabnik komunicirati, se izpostavijo goro nastavitvene kode, ker imajo nastavitve. Običajno se veliko tega znajde bodisi v viewDidLoad ali loadView:

preglasi funkcijo loadView ()
{
    pustite helloWorldLbl = UILabel ()
    helloWorldLbl.text = NSLocalizedString ("controller.topLbl.helloWorld", komentar: "Pozdravljeni svet!")
    helloWorldLbl.font = UIFont.preferredFontForTextStyle (UIFontTextStyleBody)
    helloWorldLbl.textColor = UIColor.whiteColor ()
    helloWorldLbl.textAlignment = .Center
    self.view.addSubview (helloWorldLbl)
}

To je dokaj standardno za tiste od nas, ki se lotijo ​​vod Cocoa Touch brez .xib ali .storyboard na vidiku. Če delite mojo ljubezen do pomanjkljive metode viewDidLoad ali loadView, lahko to odložite drugam.

Recimo, lastnost:

pustite helloWorldLbl: UILabel = {
    naj bo lbl = UILabel ()
    lbl.text = NSLocalizedString ("controller.topLbl.helloWorld", komentar: "Pozdravljeni svet!")
    lbl.font = UIFont.preferredFontForTextStyle (UIFontTextStyleBody)
    lbl.textColor = UIColor.whiteColor ()
    lbl.textAlignment = .Center
    vrniti lbl
} ()

Lepa. V lastni knjigi Apple o Swiftu ugotavlja, da "če privzeta vrednost vaše lastnosti zahteva nekaj prilagajanja ali nastavitve, lahko uporabite zapiranje ali globalno funkcijo, da za to lastnost zagotovite prilagojeno privzeto vrednost." Kot smo že omenili, UIKit nadzoruje donos veliko prilagajanja in nastavitev.

Eden izmed lepih stranskih produktov pa je, kako zdaj izgleda lookView:

preglasi funkcijo loadView
{
    self.view.addSubview (self.helloWorldLbl)
}

Upoštevajte pa „()“ na koncu zaprtja v izjavi o nepremičnini. To omogoča, da mali čarovniki Swift, ki sestavijo vašo kodo, vedo, da je primerek dodeljen vrsti vrnitve zaprtja. Če bi to izpustili, bi lahko primerom dodelili dejansko zaključek.

In v tem primeru je to.

Pravila so Pravila

Čeprav imamo novo sijočo igračo, se je nujno spomniti pravil zemlje. Ker dodelimo lastnost zaprtju, preostanek primerka, ki vsebuje, še ni bil inicializiran. Zaradi tega, ko se zapiranje izvrši - znotraj njega ni mogoče navesti drugih vrednosti lastnosti ali sebe.

Na primer:

pustite helloWorldLbl: UILabel = {
    naj bo lbl = UILabel ()
    lbl.text = self.someFunctionToDetermineText () // Napaka prevajalnika
    lbl.font = UIFont.preferredFontForTextStyle (UIFontTextStyleBody)
    lbl.textColor = self.myAppTheme.textColor () // Še ena napaka
    lbl.textAlignment = .Center
    vrniti lbl
} ()

Primer primerka še ni varen za uporabo ali pa ga morda ne bo končal postopek dvofazne inicializacije Swifta. Enako velja za vse lastnosti primerkov, ki jih je mogoče dodeliti ali inicializirati, ker se zapiranje izvede takoj.

To je posebna, vendar upravičena pomanjkljivost pri uporabi zapornic za inicializacijo. To je povsem smiselno - in to je v skladu z enim od treh ciljev podjetja Swift: varnost.

Bodite luštni s kolekcijami

Eno področje, kjer se mi zdi ta tehnika še posebej uporabna, je primere, ki predstavljajo eno od mnogih različnih oblik zbirke v Swiftu. Od številnih talentov Swifta je rezanje in presejanje zbirk z močjo tisoč titanov eno mojih najljubših.

Razmislite o naslednjem primeru, vzetem iz inicializatorja v projektu, ki ga trenutno delam. Razred, v katerem je ta koda, ima lastnost [Developer]. Ob novem zagonu nastavim njihove začetne vrednosti iz datoteke .plist. Nato se shranijo prek NSKeyedArchiver.

čuvaj naj devs = NSKeyedUnarchiver.unarchiveObjectWithFile (DevDataManager.ArchiveURL.path!) kot? [Razvijalec] drugo
{
    self.developers = {
        pListData = // Pridobite podatke plist
        var devArray: [Developer] = [Developer] ()
        // Nastavite devArray iz podatkov plist
        vrni devArray.map {$ 0.setLocation ()}
                       .filter {$ 0.isRentable}
                       .sort {$ 0.name <$ 1.name}
     } ()
    vrnitev
}
self.developers = devs

Ta pristop mi je zelo všeč, ker čeprav ga ne uporabljamo izven inicializatorja, je namera kode zelo jasna, saj je odgovoren samo za nastavitev lastnosti.

Ko postanejo večji inicializatorji in preglasitve viewDidLoad, so tako razvrščene stvari (vsaj) razveseljive kot darilo v smislu berljivosti.

Pridobivanje NSCute

Če resnično izkopljete inicializacijo stvari z zaprtjem, vendar imate hudo pomanjkanje uporabe tistih funkcionalnih $ v kodi, razveselite. Če uporabimo nekaj spretnega Swifteryja, lahko avtor neke kode, ki sklepa na vrsto znotraj samega zapiranja, kar daje nekaj konfiguracije profesionalnega stila. Upoštevajte to kodo, na katero sem prvič naletel na vedno informativnem NSHipsterju:

@warn_unused_result
javni funkc Init  (vrednost: Vrsta, blok @noescape: (objekt: Vrsta) -> razveljavitev) -> Vrsta
{
    blok (objekt: vrednost)
    povratna vrednost
}

Všeč mi je, kam gre to. Javna funkcija, ki zapre z vtipkanim objektom z uporabo generike, ki nato vrne to vrsto. To pomeni, da se lahko obrnete in inicializirate stvari z več vrstami informacij. Naš prvi vzorec kode bi potem izgledal tako:

pustite helloWorldLbl = Init (UILabel ()) {
    $ 0.text = NSLocalizedString ("controller.topLbl.helloWorld", komentar: "Pozdravljeni svet!")
    $ 0.font = UIFont.preferredFontForTextStyle (UIFontTextStyleBody)
    $ 0.textColor = UIColor.whiteColor ()
    $ 0.textAlignment = .Center
}

Čeprav se morda zdi, resnično odpravlja potrebo po spremenljivki primerka znotraj zapiranja in se znebi zahteve "()". Zelo lepo .

Končne misli

Lahko bi rekli, da je uporaba takšne tehnike šest v eni roki, pol ducata pa v drugi. Čeprav je res, da so vrstice kode, ki jih je napisal programer, v glavnem enake, vendar trdim, da sta njegova umestitev in prilagodljivost idealna za številne scenarije.

To je zabaven način, kako to storiti, in obstaja celo nekaj načinov, kako narediti isto v našem starem prijatelju Objective-C. Ampak hej, več ko veš, amirit?

Do naslednjega tedna = {pustite teden = teden () teden.advancedBy (dni: 7)} ()

Jordan Morgan je iOS programski inženir, ki vodi Dreaming In Binary

Če ste izvedeli za uporabo zapor za inicializatorje, vas prosimo, da nadaljujete in NSRecommend (to je, kje: spodaj);