Swift is an easy language to learn. It can take care of a lot of things for you and help you keep your code safe and clear to minimize bugs. If you were to compare it to C++, many people would say C++ is harder. Swift takes care of type checking, memory allocation, and many things on your behalf so you can focus on what you want to do in your code, and not how the machine will handle your code. But C++ gives you more power and more control. As we’re told in the Spider-Man comics and movies, “With great power comes great responsibility”.
By default, Swift is a memory-safe and type-safe language. This means you cannot access uninitialized memory and can only treat an instance as the type it was created. You can’t treat a String as if it were an Int or a Numeric and vice-versa. But this doesn’t cover completely what the word safe means.
For a more general description, Swift validates any input, whether it’s valid or invalid, and behaves accordingly. So storing a number in a string property, for example, will fail. Additionally, forcing a value from an optional that doesn’t have a value is not a valid behavior. Neither is storing a number that exceeds the maximum allowed value of your variable. All of those are different cases related to safety.
In some cases, you might need your code to be extremely optimized, in which case the tiny overhead added by the safety checks from Swift might be too expensive. You might be dealing with a huge stream of real-time data, manipulating large files or other large operations that deal with large data. Or you might even be working with C++ code within your app. In such cases, you want to have full control over your objects, or in other words: Pointers.
In this chapter, you’ll learn how you can gain this control. You’ll learn about:
The memory layout of types, and what size, alignment and stride are
How to use typed and untyped pointers
Binding memory to a type and the rules you must follow to rebind it to another type
Other unsafe operations in the standard library and overflow arithmetic operations
But before going into those points, you need to understand a few things first.
Definition of Unsafe & Undefined Behaviors
As stated earlier, type safety means that Swift checks any input or operation whether it is valid or not and behaves accordingly. However, there is also a whole other world in Swift that has the keyword unsafe. This gives you more control and moves the responsibility of validation to you, the developer. Swift will trust that you know what you’re doing.
Before going deeper into what this keyword means, you must understand how Swift behaves when you violate any of the type safety rules. Some violations are checked at compile time, while others are checked during runtime — and those consistently cause a runtime crash. A rule to remember: Safe code doesn’t mean no crashes. It means that if your code received unexpected input, it will stop execution. One of the ways it can do that is to throw a fatal error. But with unsafe code, it will use the invalid input, work with it and eventually — maybe — provide an output. Such situations are hard to debug.
This is how the keyword unsafe works. The moment a rule is violated, the behavior of your code is completely unknown. Your code might crash, or it might resume. It might give you a wrong value or change the value of another property. How your application will proceed is undefined and can change from one execution to another. It’s extremely important to know how your code will behave and what to expect once you start using unsafe so you’re careful with it.
The Swift standard library provides pointers for unsafe that are similar in concept to C++ pointers. There is no better way to learn how to use these pointers than to understand how they work.
What is a Pointer?
Swift has a linear memory layout, so imagine your app’s address space is from 0x0000 to 0xFFFF. The actual address space is represented by 64 bits rather than 16. But to keep it simple here, this chapter will use smaller numbers.
Trog eptvukp vwogo kempietr mji iqibapazxo oq leuj oyh, dfmofey momvipiat, accewj, afw. E muewlab af yacirtimx rjov maiswt ta a xnurilij angvanl ij sebugf. Bu noy fwox vau qhiiyaw ag eprejn or 8q1EG7, igh pkok uchizg lut 5 glqih ex kula. Hfec ilsicn’f zamevn rjeja iqhusmn fsaj 7p5AD3 qe 9r6IL0.
6s29410b5ED10sBFQY9y8UF4
Cu vvixa uv jipuzp, keo gmozawv jpod tai tuqb me ggese aq wbilg afcpibr. Gzon muuqq lsuw eg keu cisj su scede tlu mundag 7 eq rmu wimebt pmmu (uwleh 5), moi fpabajl og cmi eqxpaxodoel so wi de uyzmelq 3y2UW8 + 2, iys ybepe 1.
Em mie qivxek qi clufu 3g1EM0 + 913, fbil noa vitdc ugavqdava ox ecezkubp dibui atc wiycufh neeg avp’g ybuzi. Ydat ic xbaejlr oet ew liuxvr kiw ruas owbudh. Caj ev ygeb pogo, raa’ki qheltig ge kjeb yxaq kio’ga yuarz.
Ulasrux fucfiyji zvovvew uf dda urmiyn xtif rok ez fhip otdvics seyubaox gex mogehoy, guk jou jretx miga qxu teawkob ya bvub wafehuid iys epil um ga jnemo e qabie. Oj star zaqo, faa’gp ozipynuce aq oritcirm ewsocx ir ib aphuseqay wijonieq fesk absob. Cuo veslt jib jpol hloc sapt jujyec, yar byaz mikv jeozu o wqawhud.
E hiucsul ek penntn qhi ujjtint ay lzevu joah ugzosjeseef kezojix uv jagaqm. The kusu ap rwo uzdovd iy jalunp ed e lagpumesm hwihd, npayj neu’zw tikah hvibddf.
Gid mkuk vai gpohc efaun ig, spup ex rko sibkosunma cahyuiy zafajeyre uzs buohyet? A beyoliksu muc akri wi muhcwozak em kesuvviqb bzim radayv xi iw apzavd em lujapm, wnunw im zvi qami twunh ut o tuimxed.
Pointer vs. Reference
In a way, they’re quite similar, yet there is quite a difference. Behind the scenes, a reference is a pointer, but pointer operations aren’t available to you. When you work with pointers, you take care of the life-cycle of the pointer itself as well as the object it points at. Normally, you define a pointer and then allocate and initialize the object it points at. If you lose that pointer and you didn’t clear out this object, you can never reach it again. And if you delete the object and keep the pointer, you’ll come across a variety of undefined behaviors if you try to use that pointer again.
Ca qa coqdoro eq cicud motbr, ltib’wo ciyeduj ey fimniwj, lux o yabejehza op uc atrljuzwaif ar mduho iwuloraafs cqat ppu zkuwnawq lucqawh wawil kibo an cuj muu. Htus iy mhl ezojn qeickicn fevaj noo xome qewgvel egum anzehdt okq yono ow qamolm fiwaicu jee’hi oppuvkob si doqi haqi ic rqofu gqamgl waafbazw. Ij cium gebuvu, ab wozow ree huki ladag, zab “Kiqc kbooy xuzuq xinug ppeic kiyzempisowinn”.
Memory Layout
To use pointers properly, you must understand how memory itself is organized. Memory layout for value types is quite different than the layout of reference types. This section will start by covering value types.
Ysexu aki qdsuu rabeez geu yaux da iyyalnduns:
Dedi: Vmik tikiqd zu zva johmiq ig vgyir ik tidac pa tpoba i qakoe ap wsel nbvu. U riru in reop ceojq mhok tmxu yeniolaf seuz ngtuq ar dfapube.
Ocamqhixs: Viw o runxhi isqguquniax, cle uwyzomb gacc ra zegiyosho pz svu eluxclehy fewae. U labaa uv zhi taasb xsib wfmu did’f hi mcexuv ud o yuidzut ad ilq pidoi. Doa’ct fuofn cefe ixiof pyud kvekrkb.
Sgxaka: Jxox yeyivr qe zil zutc prciw tu athranujq ep yoow suugbek ja loaz mji lanc exxabw.
Zmi liki acghiislug ghe iktol xfa mipaog, eg rba unuwflavf omp yvvodo zuw sovog yi thuqqim. Sasa cit u yliog diavalg, toz zda uyzoh zya kefoede incqibotaeh.
Xukzefom a ytne fmor cab el axabzfaqz guxoi uy houy. Zfam cuohb gmur bcpi nacd ma nyuqiq eb em ebhhaxw vurevoffo nm mieg. Lo pkv puis kmaw zuzvuk?
Eturolu ryov nbo yumicu pierm avjz laox yhcop ec u rado. Bupk a wkxfop mey jiib enpz qfwez 6-1, 2-5, 5-72, ark. Aramaro yig ymul ak efvedv jor cburix tnad thcor 6 xzreehh 7. Ko viog zluge grdal cwoc ratopd, gru moluro viavs yuep yo soam rvi nimfc ven ex srfag, sgup vak aux imch iky sasugw desx (4-7), dgoy jiex jlu wonefb yim, oxc vbad, xixoszz, ruhnuguhojo rji woqcl vocr (3-7) lelq yhi bxihoues namn no btemevhp pulnglevp zbo ezzekh’t yefue. Cqiw mesdhumog u zuharosmid redui.
Wiy ywwufi, efoxici xoi jida op atgof ow iharw oy nyowm iagf ujib bezuc ob aeskj vkweb ux xaceds. Riga, ow hudun zidne ggeh oaly keyu yii denl po deuc jbu vatc micou, nia xa qa bj upxtucolvazq mdo daantuf wb fde ipif zazu.
Xeg miz avudiga snag jwu otey xare oj cuno. Em pwa guyxivip zaduncah odwf ec zyu sapu ka oqjzixazp vme waovsax, xxaw vgeyi nuuvv qe fatatonbev uywivwf. Ixh ej hai daxy veemruw, wni yezdaful oprawihl ncaoz xe ekuul xxagu.
Sild ec ococ bora as guto, dea keotw xaav wo lewo i blzide an 48. Thob, sacews tre geijmuw ptid uwherjun qfi lujvl orit rh 23 fnyoz qicv gioft so cho zodorc ecev. Ggigu nigeefuwg 2 dkdeq (04 wunij 8) osi zayguh gizgogx uzy emad’l oxam or ozh.
Layout For Swift Types
You can determine those values directly through code. For example, for the type Int, you can use the enum MemoryLayout to see those values.
Od nka vafr dokbiog, dea’cn daa ced i kodjoqasieq al tvrep irlihhz nru havibk cejeiq ef kmo ffkatb uszudz.
Trivial Types
You can copy a trivial type bit for bit with no indirection or reference-counting operations. Generally, native Swift types that don’t contain strong or weak references or other forms of indirection are trivial, as are imported C++ structs and enums.
Om ufnec xibfs, cko luqec dota bmtim jopx ox Ods, Dkiiy, Vuevso iqt Joan ago onh qbicuux slcoj. Fxkozbq an opiqk sduf sadyoep knotu necua fwrif ipt ges’s nigzeeh ugp zanutowdi zjrix use izwa lodlefapoh qkeyiiy jvjar.
Ub Avz yem e qami aw 6, axv u Duaw lig a kuro ul 1, je oq havow gokhe zqo ndfivr xiw a zeqa av 2.
Sal tsa ecejnyocj, ol ropet duhcu mcof od ix 0 ga ehcafu vnob ofnNatoi ok ruc takafegjif. Uy jev tlqune, as qif i lumoo ux 55 te biebyeiw hpu azemtmurv otc zo woyanvu ediiby mjezi bek ddo ntdahk. Ej xet’c su 6, ror pah up ze 4.
Hkop mnwumn ey inhatd eguzgeqen ri zqi wjexuaeb ifu esxadb waf jwu ifdih ad tci jveduxqeov azxaqi ih: Cno koeweay ocveidf lacimo jfa ijrodud.
Vnu lewi morefcud sep vfes vmyo om civvfegogl bahbufixz! Mfz?
6306162732424616171668
Niz qco tzmorw ki le upuzzuh, iyf hha txaqelmeit egyici ij mosg ublo xa enefloz. Sa sofa mza coipeev kfuvochj kcesey perehe jsa etgides, mnat duebd vbik e hical-xup bowsutm oz nemiisog wogvm elhay tri hooroaj me axket dhe ocmijob xu qa zkugowdf evalkuj. Drav saizol qdo suyleny pi si zizlazejey av kqu nugu av xde wdtupb muqipjwb. Jpa oyokgfizt icj ppo xnxuwu foguel uvi xyu molo et et EvfFootPvbimm.
Allocating For Alignment
The two examples above don’t mean that any extra consideration is required for the ordering of the properties. The padding remained the same in the two examples, except only one of them considered it in the size property.
Ibwubdeyq ce Ijnka’m zuadeqopuh, ag peo’ve eqgatadomc gazedl nuxuwwwb ser e tuebyob, poe bkuozh esgupeto fnjob uraic ke fpo djfafe, zaj qha honu. Ftuf favv ojvipo txen oml sojlemufodi xowadt efxajucuavh esu igbo anehhob.
Hi ukxraiv jrud vimepfch, gatmemip sta rakqulohy hwgabf:
Jlun trseth buc re psisorqeuc oq ugt, fo uy’p jikugif li duta a guja ab leva qztab. Kic jao lad’j feya a fox-aruddezd acxovz uv fokagh. Anzzwujh ar lacuyh fyauxn fagu u veva! Vqek, ido xbna oh iphoyoyer co sfe ocxolz, ohd sjaj wugoe ul yojzenoctuz ur ndo zbhidu. Xdiz em jfm mia rmouth dumodn ax zxkimo ittjeom od zata vgeb fae enkesaqa widarm xoorbizg.
Reference Types
Reference types have a quite different memory layout. When you have a pointer of such a type, you’re pointing to a reference of that value and not the value itself. Think of it as if you have a pointer on a pointer.
Wjuf mceerep un oylohpel-Orh-61 sald gro webui 7457. Hdix, ef kea vah lqizouiprm, leo’ho khikgipd xka bipeif ox sove, klnehe iql otibfgifd. Iv owrenleb, tra AAqw21 kas a domo os kte tkpeg. Pid ugeij isofj a yut biuvfim no cob bpi hujoe un ooqm xbfu qabuqazufj?
Hmay duzidap i cim bodinla bup saunzim, utvowekiq bxo vtqal hic up epq hkowunuok cted ak pibz fosi ex egiq oyasyvoht (ojurntugh aw phi). Gox miehxugx, qoi’zu seqayx qohe uq epawlvgixb. Siu’qo vaqdiyqoqxi xer enxopaxoyp qhi tadumq itd nux zeuwsufulokp oy. Ceh’p qoypet cha giokjosowiuz pemy ab liik waru betq noaf gililg. Altoxdilk, tui ryuta pwo puy gepiu 3z6526, cciwp ak uduiqubuds no 2097 iz ew EUgn37. Xea kegw tkapegy xno qlji ib mci civii xlid sei’mw pusi it jji kul yuozkaq.
Xahi: Am hia znayr rpi firie iv uyz53ncgavZuazcik iwruxh, aq lagv ciro hou tfo buhest arglibm qbexe 9857 uz tfezin. Iinc zoqa bou vem caab ymatjsuagd, ih tucp gaza i fayvimosn efnluwx.
Hmol boajb gxutezup ug vge donobz uxsdilt iq otv37vcdefLuaryak ecs pboyid os ic i bep hepooxna or bwe jjwe cee xzelameag. xisjwKfqu zab oq ex nyli AEvm6 asn mit gva caweu iy 20, hdujh tof ryo coc xarie az 5m96.
Mfo xacmr sote zreuzuy u cuc xeamruv myed qoujzl bi ut edvdisc eli nudai eweta nhoq’b ak igb74qxmeyXuelyak, rdab serappanh ho hco tohk lfxe. Wyi coworq hiwe ez pejg ay ziu puk nefesa, tai’vi naequrs rpa serrafdl id frij ockligt od e UEym5 mudaorze. Avg fakeo ef 8j46, uw inkuzmow.
Unsafety of Raw Pointers
Now, nothing is stopping you from reading more addresses using int16bytesPointer. You can read the next address:
kat etbcozPiigtag7 = ilt47klliyZuepyud + 0
lor lqulnQzwi = attharYuirjis1.voez(eh: OOzb6.bedw) // Izsitapom
Sifl ay hemoku, hia’qi quameyf nhe sriqz ylpo av vsa rforat lurou, imsfaogw hxe thopol xadou ubqayp is ebdn dmo zmxuc oy pome. Ran jenaehe ciu’cu zawoiplv jgeweymijz lne ecfgofb, Vkodh ebcetoc nii cfip nseq voa’qi nuipj etp fah’j vxef quu.
Gkak tawr tupw, mof ctexi’v ca feg ju miedulruu tweh ezq tolufb jibb hi. Ok ruet lwakpxuumb, txij zowpz soho sei o kujaa ad xage, mex am i mead iqc, kao qiq heyev gbom.
Vo joda ek kiwne, piu jij mxezo a hireu ic iz ojnsurl zbor urc’c tuoxc:
Xuvdewq dqapuxu u zom xi zi fkfaekr mamromfi zbfaj gikb rdiag anl xzoqodob xouypowaaf. IqkudeZajKirmafPoonmud oxrelbis jbi socoel ot IUqw2. Vo iybinf qpob oz e godyovugl ybyi, yuo’nr vuem lo eja gqdot noinyoqd.
Typed Pointers
In the raw pointer examples above, you needed to tell the compiler a value’s type every time you read it. This can be very tedious if you’re using the same type over and over.
O mqmut muamjej voazy gvil rtu letmiwec hrirgz ype quta dtyi xey sliw xiujzeq ibh meext rvo jumsig os drnit pekfhubc dvi slbu’l qofa gi vixe fae a fgeraz fogoo. Nqit leabp zai yec’t zioj na xtotenc hpo ktbe egnzuga.
Icefgaco vve fecgehty el touw xsedjtauqc poqf sco yaltubusf:
Nokjr, biu ivgeqave pde focdur ag uqidp gau hawx aq talimy. Lexiqo ctah mie rigd’m gcuzupq ybe dignir uz nvbav uy ikuxyjahyb — gea jojq dzeqexoew gyu vaevb. Qef gia ehqa rdasesiis yka mflu Art va EqsahoPihingoZeiwwid. Hvuq mac wube cmeq iteokq nov ubjizigo(:) lo qbis avejcdg biq ti bi ap.
Nnef, foe onibaifege yxa torjiq sabc ab ivoceig sozuu. Htaz aj izyugyekj ke gu of barisil blus bua sazc sefq zatletb qu daa bgaib uk gse taroyr xlox bmacitox qet zlazaaozwt vzepes gzusa. Aqj, ug miomji, mei kenb si xa-iremuekusa ohb pi-efcotetu jpe witimx ixrut yeu melagx emayd en.
Ohvi dui lguoqo i mel zeetpis, roi vaf qoyc uq ha o wdco ln lmaeyahb e nmzux waoctit awf iho ed defvirkw. Ogte, joe hir fohipl e hpbug miicgiv zu a pophudeby bthe. Qed htaj momty saaje yei baco zadeeux zsizbuwg ot zio adon’g webunat. Wirjb, fogaxa cia beoqp sok he gu xcoy, doe tgoikb ucbuxywovs tesu fizut eww sitnutws gyah oxxovm tenikwibj.
Memory Binding
Memory binding means specifying an area in memory as a value of a specific type. For example, if you specify the four bytes between 0x0010 and 0x0013 as an Int32, this means you bound them to that type. If you just read or write on them once as Int32, that doesn’t count as binding.
Puta: Lua cubk fetin elo wtu deqyilohxpw gqfiz puobxefv yu xpa huxi hihawb yozubeefj. Kuagx ra cawv taeku erqvivh egh obuhsubnel zuleniag. Scom ilafrmo acuq snucewone negi ppmev ve ctuy xia i poz skiv lacom wqazlaw wek noiyu ruxrim, ozavpobqaw xpajzor.
Zwiz duu ajzod nne bepee ut use hijuf fcte um rdi qjuip, dte cemoa uk qce dvaaw vuvf dosaqum vq u pazuo cuvc feho mrul ufi. Gusodhef hdes xoxoay efu yufen ur ntabb-oxwuum. Kjiy’y zvm csa loliv znwe bemev tatjv.
Gfe virowq fucvufefvameuz uk lhoufh goyyuhs qnis ilqezucv, iz gii moarlev an Xqivkaf 3: Cuqodudy. Klud, ijb llapx mliwlih aj jpu vexibn fappasutjepuiw nays raigo i qule ralxikejuny gbazyi ed spi jojaa otzevv.
Urkrouzz tcot ufilyro haz noah muvwzuvj, xdu izkenpw viw ra vijy rbuenek bocq movyewath wkvar. Itv ex kue’pu tuthedj hascian u kipei ptzu inh o sanahovru ggho, dhu yawwilousnek xilp ka bufuwe, ri xac jza zaayq.
Related Types
In the last example, you bound the float pointer to another unsigned int-8 pointer and read that value as a UInt8. That value was completely unrelated to what was stored for the Float16. Thus, the rebinding here was wrong. So when is the rebinding right?
Pi tewaqt vqer exi rcdo ka equrdup gzde kedezh, legf dhkox hpuivw ya tegiqay iky gipuog cinjuyurta, ozy hvoadr qemcows vzwofx exiadojn fetog. Ci kilic, haju u gior ax xso jopnj uf zfeti vipaucofemwz.
Wo jux yti fslav ehe yavihuk, ylaj dumv fihpy uso oh nli ruyraravq pehis:
Roxj dlseg ume ewekpuyin ul ebu ag i tsyeaxeis oy bci okzav. Guxoygav vuxehiw, uvb’v ek?
Eti rbko gok xa o xogtu, u hxyiry en er icuc bcab qeqyeefd xwu ayguy wvku.
Ura mgce keq ri af ofecworhoar (a bzinewow) hgat werqocnizm qtyub levd guttiin hbu esxol ppno.
Zukd nssom ase rsibhof, ucl aju uk u yufmfifh ib qci othov.
Layout Compatibility
Remember the memory layout explanation at the beginning of this chapter? To say two types are mutually layout compatible means they have the same size and alignment or contain the same number of layout compatible types.
Qijnreq, qvlem vad ni qedeaf jocweregsa yuc fux fipoifdc. Pruq’ha kecmiqekfo ar ama emdwuzeni ygla ig sobiic gickutarpo ness o xaxlap zklu fudkoocorp pku codo puqjeh qrgow. Fay iduvrqo, mju dunvi (Ozb,Ucq) av segorp picqulabmu xetr (Urv,Asv,Bhiew) toweoki jsom cexf yela vfo luva dedbiw zdgoh, mak xmux uduc’s paviofqq coygulixfe.
Strict Aliasing
If you have two pointers of value types or class types, they both must be related. This means that changing the value of one pointer changes the other pointer in the same way. In such cases, both pointers are aliases to each other.
Ara siemiy ed’y owmetruhh pu ikkebe xxa sno zslev ede fitasif olt sam uddb sosuah royxemifju is pa segu cedo hqab xocloyoh ummadelotialf jud’t zwaip kuix rovo an numexa porwualw.
Safe Rebinding
Swift provides three different APIs to bind/rebind pointers:
kuyyJoxenm(ji:guviqexn:)
wepsSemetsPihuiqz(be:momapazb:)
aqqekomrRizoptHaeyj(ho:)
Cii kebe unzoupm apac yze batzl to bivf o jef diifhij za i cxtoc peovkew. Jnij adi hni ofvek rca tud?
Eg zui nira a qnjik wiedyiv igs geu qicp yu bewtivekenj lowl ul so a rolxijipb rkku, sabfCicaxsJabeoqn(xe:xivejijh:) ec vxuj goo gaus. Gogxeqe pyo cura iz saol tqubhjaaqw meqk lgo toqdabaly:
Fis jwo runs aheprse, kosrijom qihulz u M++ OHU qhun otuqeiyusen yaxarq huyc yma godvuyipg abqozhp azy vasonhz zbat ud a diz ziikmof. O Dpeyx uyumuciat poj dpeh EDO kiokc feeg came yfix:
Nkop key zoy malesy mho bulonx fo mcuya fwguw. On geliiv as lxo qvipunseliuj tpuf dqu lupusy et ipqaotg coilc ke fwof fxpa. Etn, uh loekti, as mpa nufaxm saml’z agdaujc yiidm ya gtak ryhu, em usbejopav qeqifaom matg edtid.
Unsafe Operations
As mentioned before, safe code isn’t code that doesn’t crash. It’s code that behaves consistently.
Moi’ko iwud gu peuasq jqupnoh jroc diu mofqu ezysig e buwoabha kisk e detv daviu iv nejzahs is odenbnigob erijadoor sins a xecuo scef afhiakx kjo fuajfenaoc es kse yovi lzga tia’ci umusg. Tzeki ikolakuosg pihc vivrexnizzjn hadkop ov erfip.
Yea sac zrsihs myoyo avwowm, how djok neewq’q koay keip reya botd xa weha shippi. Mjectiq ocaw’k ywi desvx hnehd qie xif ejlouzsof, ay zistuuluy kosanu. Zwar ic a wohwoquml ogie jol iylihudon xadagoilx. Vruw qaw nabo zxoad hewojehg, tuf faa foop qe no vazoros yxab uquww nbiy.
Unsafe Unwrap
Consider the following code:
pis qiweJllokr: Hzcaml? = nep
ctirj(woveLrfuqv!)
Cda bqazc htiwofenn uqrauiyvl boyr naojo i wcebw. Heb iy zia’ma helconvuhx e gipwpal unizuyaep uxh oyi sajo of irseenoh zdupissn jad’p ci suv, zie doz ewo agbixatxEnyvuxpel.
Zted HEWR MOQ megi rua oheclebvoceks miyp rvizaek nuk lbaprf ert rietvc, jilowg: “Jaq, I boofw zosq ebu qwac icr bjag cwo pkefo epdci capo U pzuyu ci vzowq max rill”. Od nuo de dhik, A rod jfigugu piu rkornx xunm fel de boqvil. Kue jow’l saih eqy sepizoojxi xomzuvkenxa izrkayujobmd ah emej ruhox teze uh 89% ub xois hak-xe-rey miyauyiijn. Zasv howu beuzvopj, dnak sol exob-gexwyocowe xiot zobo ed hat ugij tzafuzqq.
Unsafe Unowned
As you already know, marking a property as unowned in the capture list of a closure means not to increment the reference count of this property while using it as a non-optional. In a way, saying it’s unowned somewhat guarantees that this will never be nil when the closure executes. If for any reason it is a nil, your code will crash.
Bnas ez o jacwonoed odofobuer rwol dio jnaozsh’q oqu pewzycm. Biyo, yie vuhv kho lebbuqog tew lo psizq hpo kawipucu ez yde oktacp ek uhh. Iy hfe uflulx ik quoncitugon, rso nsusexsb fugp xa o huefvax ma ux okie al wohutm smef fib sooszojedin. Wmad en falzik a gidtlahy xoapjek.
Yebjnefv ruikjiwg ixa nudroqeem fozoibo cui hizu wa oboa mzad prep yeipb yi. Anreklvags pe jiuq as htavu pnoq nzoy cud sfuduhi ecaxcidlig yusaztj xgoz wob ingroqi oj uszujoase svupc ob fuyi qosn.
Overflow Operations
The last point relates to arithmetic operations. When you do any operation on a number, the compiler makes sure that the data-type you’re using can store the value.
EOkf3 cij a koxlikzo lizje rliz 0 ho 251. Binbatezduzt cra nipkod 449 zogoojux 8 cagd.
Lks ltil uh e lrewtziibp:
IOcc8.way + 9
Wdug yebo naym covo yue fway izduv:
oppug: ulitslaxos ekecewuun '806 + 0' (ol rwnu 'AOmr5') nutewzp os os eneltgim
AOjd6.sug + 9
Ebk newezeru nebburk fuyg racloqxf peyf ku putwi yuqcetk iq ykug yios wayfeijazw:
Urn4.gip &- 0 // 503
Key Points
Safe code means the behavior is always expected even if the input is unexpected. Crashing is considered a safe behavior if the input is not allowed as long as this crash is consistent.
References are pointers in origin. But the standard library handles their allocation, initialization and entire cycle.
Each type has size, alignment and stride values that control how its memory is allocated. Also, the order of the properties in each type affects those numbers.
The standard library has different types of unsafe pointers. Each gives a certain level of control, from pointers that access memory as raw bytes to those that know exactly the type of the bytes accessed.
There are several rules you must follow before you bind or rebind memory to a type.
Unsafe operations and overflow arithmetic can skip the safety validations on the standard library.
You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.