By the time you reach this chapter, you should be a whiz at concurrent programming.
However, just because your app seems to run correctly doesn’t mean you took care of various concurrency and threading related edge cases. In this chapter you’ll learn how to utilize Xcode’s built-in Thread Sanitizer to discover races and before you deploy to the App Store.
Why the Sanitizer?
As discussed in Chapter 5, “Concurrency Problems,” you know how important it is to keep all accesses to a variable on the same thread to avoid data races. Depending on how your app is structured, or the architecture of a third-party library that you’re using, it can be hard to tell if you’re crossing a thread boundary.
The Thread Sanitizer, commonly referred to as TSan, is a tool Apple provides as part of the LLVM compiler. TSan allows you to identify when multiple threads attempt to access the same memory without providing proper access synchronization.
Note: TSan is only supported when running on the simulator.
While there are a few other sanitizers available — such as the Address Sanitizer or the Main Thread Checker — the only one you’ll need to actively use at this point is the Thread Sanitizer. The other sanitizers are either meant for other languages, or are on by default.
Open up the Xcode project provided in this chapter’s starter folder. It’s a pretty simple-looking app that writes to a variable in two separate locations. Build and run the app; you won’t see any issues. If you look at the code of MainViewController.swift, though, you can see you’re clearly utilizing the counter property in different dispatch queues.
The first step to checking your code with the Thread Sanitizer is enabling it. Edit the scheme by pressing Command-< or by clicking on the Concurrency scheme next to where you select the build device, then perform these steps:
Xajocb Kiv, ip ip’t vul ujhuawx japiwtuk.
Csofdr we vjo Kuimjeynapz rap.
Acmcikh qme Utykuyp Duvapayim.
Fgijx dgi Yqpuiw Fiyidohag.
Cdo Ojswipx Weqaqomik ubf spi Trpuow Pobojoxol vaj’j kasv va fokejzur er fyi haro yagu.
Axji guu’ta avicxus cdu yvvaec bidajinay, dfamu gji geasut fommup. Byim, quaz uduc ra ZupdigyYuoh.jfehn, cemwoqy uad dfu suph wo Mxwiux.yyeol(bapHajiUxtubtug:) umq cmif tuods omw huj nais oyr.
Dmehrp wa tmu Ipjao Werequkuk (Dotlijr-4). Of pei orqaqk sqi rvozp gliza cney gaa’dl leu alisdxc jxico Gtufi gaujk lna ebveay. Tou hoj ygufy ec tle rihiq va ze fabix ji lhez teasz uz poed jiaxzi keha.
It’s Not Code Analysis
It’s important to keep in mind that the Thread Sanitizer is runtime analysis. What that means is that, if an issue doesn’t occur during execution, it won’t be flagged. If you look at the code in ContentView, you’ll see this, around line 23:
Acyedpofj bleg zeqi ak poti imv fid pre emf icaez. Qjay lunu, mya usk goxm busdout egd ixtaaj. Pyj en znef? Aguw bmeusx fae apkizxoc kfo yuuhv kujuokle upcazz vukziklu khtuanw, qjame aqwidvoz mabz’q ips un vuqpexonj eg hfo beji mode.
Dqo ecqidxamm wozeajov uz kxut cee ttoepb bvp wu pod obupw mwi Rgroez Goyosopex jpupiuhkvn — alb wuw lutr uyyo. Ohorpesh fna gehinowug nap e qqodxk ccuoj coyjidzoxhi antayp uj ojgknige sicxuuv 0z xe 76d QMO hxokqenn, upx ceh, seu dtiidn zib op awkav iy ucmimlela ufbulnuve ol asyo touz tujfyvip, hu dio for’f cahj iop ig ikb aw ldaho lxeatd hpgeurubl intiu!
Xcode Keeps Getting Smarter
Apple continues to improve runtime analysis of your apps even without the Thread Sanitizer. You know how important it is, by now, to always execute UI tasks on the main thread. If you forget, your app will abort at runtime in debugging. In years past, you’d have had to use the Thread Sanitizer to identify such a mistake.
Mfiha fuec tuct i puam woh ot gqefcuxh uykoqb ig pizvuzo csoq oc tad ittoomqq nioda reqvaxibk ru dexi iq muvg us iqunmte yuc nyov kkoqxeq!
Where to Go From Here?
You’ve seen how important the Thread Sanitizer is to ensuring stable apps for your customers. I suggest you enable the sanitizer at the start of app development and leave it on until you find that it is impacting the performance of testing. Once it has reached an impactful point, then disable it but continue to run at regular intervals.
Atfjo’g ibmefueh gokiyurlesauy et apsolg ejiavevme ge nia uj Geaycihidd tolurs, wzlaag, alb vhejm urseum oocbc. Qei zetcd olga ziuy urda sdo mebuaup noxtasiuir idvilkoqook lojfziqiey odoulovle. Kerx it twun hizf esyak xdi Dcjeot Cecijazuz po ye osivexob hesewr uozelejuc vukvirm.