Consideration on Synchronization,Atomic variables and ARC

Atomic variables 

In Objective-C we have seen declaration like this:

@property (nonatomic, strong) NSObject *nonatomicObject;
@property (atomic, strong) NSObject *atomicObject;

automic , nonatomic in fact refere the threaed-safety , atomic variables are used in a multi-thread envoronment that guarntee the value to be returned with latest changes 

by using a locked/unlocked mechanism ,in Java we have the volatile variables which refere to atomic variables , in Android we uses them sometimes for synchronization or creating singlton object that is used by many threads

the reason why we use volatile or atomic variable in multithread environment is that compilers uses a mechanism of optimization at low level , thet use processors registers to save values or pointers as a cache , when using atomic variable this optimization gets into trouble ! and It leaves this atomic property in its location in the memory , this way everytime program require such a property , it will be fetched from memory not in caches anymore, now in a muti-core architecture suppose Thread1 and Thread2 they are dispatched to separate processors each one , Thread1 store a non-atomic variable in memory then cached in CPU1 register , at this time if Thread2 access this variable in memory and update it with a new value , Thread1 cannot see this change and it still uses the value in  its register Cache!

an Atomic variable can prevent this situation by keeping variable in memory ,each time any thread requires this variable it will be fectched directly from Memory.Notice that there are many way to synchronize threads , except some few scenario It's not a preferable way to use Volatile/Atomic after all, because it prevents compiler to perform optimization , that's why in Swift Atomic variables are less used that Objective-C, in Swift as I know by default variable are non-Atomic, references in general are non-atomic, etc…


Difference between GC and ARC 

GC is widely used in JAVA and Android, Apple has implemented for a few version of MAC OS, some sort of GC , they didn't import it to IOS and then later they've been deprecated from OS X as well , we have to be aware that Garbage Collecting is a good thing to manage memory and prevent many issues related to Memory management by keeping clean memory from unused objects , but as everything has a cost to pay , GC unfortunately increase memory usage by a factor of about 2X comparing to IOS which dosnt use GC.

In a GC architecture all objects residu in memory are treated the same way , there are removed by GC at the right time when system need it, this mechanism is a guarantee to make sure every task has enough memory to be executed, but once again this has a cost , in addition of increasing memory usage , context switching will be less smooth comparing to a non-GC architecture such as IOS , GC is running and managing memory in all apps life cycle , the time to analyse & clean old residu and preparing free space is the main reason to affect performance.   

In IOS instead there are the concept of RC (Reference Counting) that is based on Retain/Release a value named Reference Count for an object ,each object reference added to program increament the RC (Retain)and when removed decreament RC (Release) , When RC drops to zero that means job is done with that object, and can be removed from memory.The recent compilers especially after Apple introduce Swift in 2014 have been reviewed and upgraded with ARC (Automatic Reference Counting) , ARC is in charge of Reference Retain/Release automatically at Compile time, Compiler detects then analyse / verify codes and count Object references , in fact Compiler do the same job as developers were doing before (MRC; Manual Reference Counting)!, this optimization in compilers helps alot many developers to get rid of manual Retain/Release which was painful with no garantee, notice even with ARC there is no 100% guarantee to make sure of 0 memory leak, Apple inroduced Strong and Weak references on the other hand in order to let developers help compiler on its ARC mechanism.


Pitfall in strong reference issue: 

When using Segue to switch between ViewControllers in a chained MVC architecture , it’s very important to know everytime Segue is prepared it create a new instance of coming ViewController! If you navigate from ViewController A  (as Root Controller) to  ViewController B by segue then press back and come back to A ,B is destoyed and not reused anymore , it’s  removed from memory so  next navigation from A to B ,result in creation of a new instance of ViewController B! you can see this behavior by setting a global variable as reference counter in your ViewController B , then increase it in your init (or ViewDidLoad) and decrease it from deinit{} ! you will see deinit is called when you tap back in ViewController B!
This mechanism is sometimes the root cause of many problem ARC is facing which result probably in memory leak! This kind of memory issue is mostely related to two opposite strong reference (one from Reference X to ViewController B , the other ViewController B to  Reference X ,this Reference X can be anything kept in heap

such as closure), when navigating to  ViewController B , these two references are created in init (or ViewDidLoad). To avoid memory leak by keeping strong reference use “weak” and “unowned” key words in your closure inside 

[weak myself = self] in {

//body , here use myself

}


[unowned myself = self] in {

//body , here use myself

}


weak var PointerToB  //let cannot be weak
unowned var PointerToB


weak and unowned both prevent RC (Reference Count) to be taken in account , reference is not counted (increased /decreased )for such an object.The difference between “weak” and “unowned” is that in case of weak the reference is optional and can be nil but in unowned , it’s not optional and cannot be nil.

 © Xosrov 2016