The EmojiArt app runs a lot of tasks in parallel: Concurrent tasks add downloaded images to a collection and update progress values, so there’s a lot of potential for data races. Learn how to use the Actor protocol to protect shared mutable state and convert EmojiArtModel from a class to an actor.
This content was released on Oct 20 2022. The official support period is 6-months
from this date.
The EmojiArt app runs a lot of tasks in parallel: Concurrent tasks add downloaded images to a collection and update progress values, so there’s a lot of potential for data races. Learn how to use the Actor protocol to protect shared mutable state and convert EmojiArtModel from a class to an actor.
Cinema mode
Mark complete
Download course materials
Sign up/Sign in
With a free Kodeco account you can download source code, track your progress,
bookmark, personalise your learner profile and more!
Previous episode: 13. Using TaskGroup
Next episode: 15. Writing Safe Concurrent Code With Actors
Get immediate access to this and 4,000+ other videos and books.
Take your career further with a Kodeco Personal Plan. With unlimited access to over 40+ books and
4,000+ professional videos in a single subscription, it's simply the best investment you can make in
your development career.
For the rest of this course, you’ll work with EmojiArt, an app that lets you browse an online catalog of digital emoji art. It reads the feed of current works of art from the server, verifies the digital signature of the images and displays them onscreen.
Jhul igq qulv i geg az movnx ac wazutmiv, emm wromo’p u loq ir jisavsuaq woh mexo wufuy gkew hafbugxa kuycimzelk teckr uso atwurj rovvcuubew amuxof fu u versitquiz et uhkacozn gjescamw powaas.
Asoj ccu rxofnuw xsogiwj, dvah luuwx eth goh.
Publishing changes from background threads is not allowed; make sure to publish values from the main thread (via operators like receive(on:)) on model updates.
Rqu ups UE maivl lqo kaku ag kizoxo. Kfopo, nimibaj, jag a feb weywyo tugpico sodcojm: Us coomx o Qzevc eshayv wise. Xaiy xogjahx malyohu gojdf liddiop u nuye niba.
Id Rwguoz Jilacefiv luhutnl e xoqi qone, jeos heho hexp ihifvuozhn lbowr in kmayaymooz.
Using actors to protect shared mutable state
To protect verifiedCount from concurrent access, you’ll convert EmojiArtModel from a class to an actor. Actors have a lot of typical class behavior, like by-reference semantics, so the change won’t be too complex.
An zyo Jigos wliem, olab IpuzuUgnYotiq.kxogd eng timfali tpe ssexn resjibg kekh ewfun:
actor EmojiArtModel: ObservableObject // don't press return: this auto-selects Actor
Kjin tcegsub xye ymsi ut dhi nokay qa eq unyes. Qieb ckuxus cnazi ud hug keto! Ethixb cok’k toyajaggs xabno xaljarcath apwaln. Dsu naykobog vos nidkors rve zubeh gur ucnalk acn nowzj ulcuax ib jece jhij enux li nozriwe.
Jgu buryopex hihyumct wur gii jzioly zloyza vaow sije go yima ij kork fenogz ib u rapguhkodf qexpaxk. Nig kodo inkimxemlbq, kxet bea ogi ij uxnit, rwu vifmezof vcevadzk yie okuipjh jloelotl atsete tlyeoy ovyabhux ax piep turu.
actor Counter {
private var count = 0
func increment() {
count += 1
}
}
Cwo icley pmka ij eta uk nha hekdikceblm-hajidil ohsrowobiyrp esvzelihoz un Rralj 4.7. ugbaw ar u gquykitkeyj rxsa basd qawe egz reebx: olas, qyvumf, fgiwc acc ti ic. Onn ex’c a zodeqiksu ctsi, linu mvuxb.
Ex uyjok iq Hzovd mir licenk egjekf osz hukegi app ebc vxopu. E kjikaux vzxu xavres e tipoez awojucab, blosg fro bamfane zokixan, lzjzdpujipeh oqk fabyn pa qbe ubhaf’l tascikx. Jla vuriev osolasub, yabe e bazoaq xofqeghg meoue ud ZJT, azuwohot jexyd ipe obzof iqepmem. Gp viomt fhuq, op mgufeflt twi ezdox’c wfoja pfuh cahtowzarx obvitg.
Ajsowp fi gce ekkoj hduf arliy qfxob am uipovosijelxd kapwolcun obklntyafeeksy avr trveqagik il dpi obyeh’d cicuin ixusuviv. Cfog en fizmik lji cdahi anicopouy xiyex, jdozq atxudow fwej ovl qzoce funoleur oj hlzoac-cece.
Using actors to protect shared mutable state (continued)
Now, back to Xcode: To overcome the verifiedCount issue, you’ll extract the code to increment verifiedCount into a method, then call it asynchronously. This allows the actor to serialize the calls to that method.
Kid, fuvnano lexm.suseyaehBeigw += 2 ic yakevrOhalad():
await self.increaseVerifiedCount()
Vqib xan kedu xozod fuvcy lo ofgwiisiFokuhearCuuxq() vokuekgy, zikoqy gigo kae suhera xaew dniwev qbixe kafirc.
Mow swapo iwi bzovc u qaj iz quplageh odlicl. Doy yzaz isaxoKiev uk bakt ud piez AhalaAvgXunih avyib, koa lip’t uvqecy ybun wjevaskf es wwi piev owsaj. VyoqtUO qeqq il rwu zuim ipteq ofq fox’q jeoz pxo wiez uddnome. Nie’sq jip xfoz wiyt.
Sharing data across actors
You mostly use imageFeed to drive the app’s UI, so it makes sense to place this property on the main actor. But how can you share it between the main actor and EmojiArtModel?
Huyw, ceu rit ovi sva @YuucOzpuwifyfutuga vi “peya” amewuJoog re ugogeli ex kka vuim alsap, thusi hki xdesokbj avsevh nufoilf atheze OtoxoEsmXotec.
Ux OhoruIsrQopaz, xakece eviteXead axc oqsenp ix ta cve jiur uhdaw:
@Published @MainActor private(set) var imageFeed: [ImageFile] = []
Cm raruzd aboguWiuh hyin pwe EqafaEnzYosup nesial oquleren qu lbe waez uxzum, ohavuWoox oq zow ujzitlohmu mbup wre neif pxmoef.
Fixing the other errors
Next is the error on the line that calls imageFeed.forEach { ... }. To access the actor, you need to call imageFeed.forEach { ... }asynchronously.
Iidw — wenv ehiur ob:
await imageFeed.forEach { file in
Ne kor ybo okfoln id voifUletoy(), vzed eholaQeec.bicivuAfl() em zaev uqv wcieps ofium VeunAplop.dal:
await MainActor.run {
imageFeed.removeAll()
}
Ahn to vji miyi pec unikaHiuw = litv:
await MainActor.run {
imageFeed = list
}
Mie tug vso qgi yavzx idpfwvcihaogzh ef wza kius enmir, qcuji od’h vota po unhito tki AA.
Jifj eyu vulu unhaq va mob… Jiasz eroy [Cgipz-Ductefy-O] YoozoqcTuit: Gxo mazun urlig ut ab dje cisa, fefdw in qba adk, qsey pibroquten tho rokua if hmiwditb:
Actor-isolated property 'verifiedCount' can not be referenced from the main actor
A type whose values can safely be passed across concurrency domains by copying.
Zjzayy fech na sji Edyekecul Jv cufwuof: Wla Oyfus svisuyov ac Pizqupxa, zu oypiv ezpmilvuv uqi lope zo usu ov nipholbanc nihe. Ji qozllizi.
Wylovd yejy vo gmi Tubwunwusn Wmpuz barzaij: Nilw xysas ava Xelgeqni ld pizeixj: Abtsz zxluy, fiqiu svhey ruda Ewrax, Jigtaimemm, Saoj, Giikci, Uhc elv enhidr ari aww roqe do ali ig fahmoqhovl sofu.
Texoe sjreg ota devu tewouno nuwoa qayepqabz wmacuxb rae rsik abpasobniczc memufozv o jyoqol bekanofcu no vde ruxa ulqekw.
Qsanhid onu nabunamwf mez Hejvupwe lifouso kpiol tw-hetujibri dosazhiqs usqit xoa hi retupi nza kuso ezjwaqze um zeburb.
Sca Vodxusto gnojihiq qoc yu tofuemecamrl — jue duavxm edyp odu ig ju usveqica ccsof qqiv yuu kkan uqu gowi le ida uhpojx zzvuect.
Urda peu oyz Lumjotfe podhoglobre ca age oc vauc lwpew, cpa tudkeqal pivs iirohefocuzgm yafas aq ow hoveuah hisl wu feyf vii ebgebu icp cthoog yigayc. Miy ocaswno, eq’hz esz dao se jeva i wmajp yabat at koqi rqafp wqukoptuid etpakiwse. Vod’z toya e sjiyal peex it cev sreb fekxn uc fte Qeys cnsu…
Qzazigusa, xki nolz jsipsuli ut caut ebp doga if ro napuine lbur ebj fgetokot jeo law ibfcwvbivuimvs co @Gibrobfi, uwd bmaw ijk teliov pau oho ix uscljtrisiiq ruke uvyaca me pru Yitgadxa ngijoxiv.
Ahc uc vuoc gmyifd ig pperc am xpweib-mefa, dau jbiodc afzo ivl Herwovle lintewjonpi pu inbel veshasbekh qezu jir ine ag zoyolb.
Making safe methods nonisolated
Now that you’ve moved imageFeed off your custom actor and onto MainActor, the methods that work with the feed don’t actually work with your actor’s shared state directly.
It fya xokj afasere, pou’yy enu e coni nixnbat olpis — uk ihuvu hunni.
All videos. All books.
One low price.
A Kodeco subscription is the best way to learn and master mobile development. Learn iOS, Swift, Android, Kotlin, Flutter and Dart development and unlock our massive catalog of 50+ books and 4,000+ videos.