When to use #atomic? - ios

I've already seen this question:
What's the difference between the atomic and nonatomic attributes?
I understand that #atomic does not guarantee thread safe, and I have to use other mechanisms (e.g. #synchronized) to realize that. Based on that, I don't still know EXACTLY when to use #atomic attribute. I'd like to know USE CASE of using #atomic alone.

The typical use-case for atomic properties is when dealing with a primitive data type across multiple threads. For example, let's say you have some background thread doing some processing and you have some BOOL state property, e.g. isProcessComplete and your main thread wants to check to see if the background process is complete:
if (self.isProcessComplete) {
// Do something
}
In this case, declaring this property as atomic allows us to use/update this property across multiple threads without any more complicated synchronization mechanism because:
we're dealing with a scalar, primitive data type, e.g. BOOL;
we declared it to be atomic; and
we're using the accessor method (e.g. self.) rather than accessing the ivar directly.
When dealing with objects or other more complicated situations, atomic generally is insufficient. As you point out, in practice, atomic, alone, is rarely sufficient to achieve thread safety, which is why we don't use it very often. But for simple, stand-alone, primitive data types, atomic can be an easy way to ensure safe access across multiple threads.

#atomic will guarantee You, that the value, that You will receive will not be gibberish. A possible situation is to read a given value from one thread and to set its value from another. Then the #atomic keyword will ensure that You receive a whole value. Important thing to now is that the value that You get is not guaranteed to be the one that has been set most recently.
The second part of the Your question, about the use case is purely circumstantial, depending on the implementation the intentions. For example if You have some kind of time based update on a list every second or so, You could use atomic to ensure that You will get whole values, and the timer that updates Your list can ensure that You will have the latest data on screen or under the hood in some implicit logic.
EDIT: After a remark from #Rob I saw the need of paraphrasing the last part of my answer. In most cases atomic is not enough to get the job done. And there is a need of a better solution, like #synchronized.

atomic guarantees that competing threads will get/set whole values, whether you're setting a primitive type or a pointer to an object. With nonatomic access, it's possible to get a torn read or write, especially if you're dealing with 64-bit values.
atomic also guarantees that an object pointer won't be garbage when you retrieve it:
https://github.com/opensource-apple/objc4/blob/master/runtime/objc-accessors.mm#L58-L61.
That being said, if you're pointing to a mutable object, atomic won't offer you any guarantees about the object's state.
atomic is appropriate if you're dealing with:
Immutable objects
Primitives (like int, char, float)
atomic is inappropriate if:
The object or any of its descendant properties are mutable
If you need thread safety for a primitive value or immutable object, this is one of the fastest ways to guard against torn reads/writes that you can find.

Related

Would there be a practical application for a more memory efficient boolean?

I've noticed that booleans occupy a whole byte, despite only needing 1 bit. I was wondering whether we could have something like
struct smartbool{char data;}
, which would store 8 booleans at once.
I am aware that it would take more time to retrieve data, although would the tradeoff be a practical application in some scenarios?
Am I missing something about the memory usage of booleans?
Normally variables are aligned on word boundaries, memory use is balanced against efficiency of access. For one-off boolean variables it may not make sense to store them in a denser form.
If you do need a bunch of booleans you can use things like this BitSet data structure: https://docs.oracle.com/en/java/javase/12/docs/api/java.base/java/util/BitSet.html.
There is a type of database index that stores booleans efficiently:
https://en.wikipedia.org/wiki/Bitmap_index. The less space an index takes up the easier it is to keep in memory.
There are already widely used data types that support multiple booleans, they are called integers. you can store and retrieve multiple booleans in an integral type, using bitwise operations, screening out the bits you don't care about with a pattern of bits called a bitmask.
This sort of "packing" is certainly possible and sometimes useful, as a memory-saving optimization. Many languages and libraries provide a way to make it convenient, e.g. std::vector<bool> in C++ is meant to be implemented this way.
However, it should be done only when the programmer knows it will happen and specifically wants it. There is a tradeoff in speed: if bits are used, then setting / clearing / testing a specific bool requires first computing a mask with an appropriate shift, and setting or clearing it now requires a read-modify-write instead of just a write.
And there is a more serious issue in multithreaded programs. Languages like C++ promise that different threads can freely modify different objects, including different elements of the same array, without needing synchronization or causing a data race. For instance, if we have
bool a, b; // not atomic
void thread1() { /* reads and writes a */ }
void thread2() { /* reads and writes b */ }
then this is supposed to work fine. But if the compiler made a and b two different bits in the same byte, concurrent accesses to them would be a data race on that byte, and could cause incorrect behavior (e.g. if the read-modify-writes being done by the two threads were interleaved). The only way to make it safe would be to require that both threads use atomic operations for all their accesses, which are typically many times slower. And if the compiler could freely pack bools in this way, then every operation on a potentially shared bool would have to be made atomic, throughout the entire program. That would be prohibitively expensive.
So this is fine if the programmer wants to pack bools to save memory, is willing to take the hit to speed, and can guarantee that they won't be accessed concurrently. But they should be aware that it's happening, and have control over whether it does.
(Indeed, some people feel that having C++ provide this with vector<bool> was a mistake, since programmers have to know that it is a special exception to the otherwise general rule that vector<T> behaves like an array of T, and different elements of the vector can safely be accessed concurrently. Perhaps they should have left vector<bool> to work in the naive way, and given a different name to the packed version, similar to std::bitset.)

Swift "timer" variable

I need multithread safe Int variable in Swift that could be incremented or decremented in different threads. Moreover, this variable must be decremented by 1 every second and notify (by block or selector) when it has zero value.
What is the best way to implement this?
Regarding apple swift block you needn't think about it.
One of the primary reasons to choose value types over reference types
is the ability to more easily reason about your code. If you always
get a unique, copied instance, you can trust that no other part of
your app is changing the data under the covers. This is especially
helpful in multi-threaded environments where a different thread could
alter your data out from under you. This can create nasty bugs that
are extremely hard to debug.
https://developer.apple.com/swift/blog/?id=10
Int is a value type. So, you can use it in several threads without worries.

Any difference in speed between checking a NSSet using objectsPassingTest: vs containsObject:

Is there a difference in speed between checking a NSSet if it contains a certain object using [ containsObject:] vs using [ objectsPassingTest:block] with the stop variable set to YES so that it stops after first match?
Also, if the set contains objects of a custom class, my understanding is that the containsObject uses the isEqual: method to perform its check and hence this has to be overridden in the custom class. Will this slow down the containsObject check as opposed to the case where the NSSset contains objects of Apple classes like NSString, NSNumber etc?
I plan to run some benchmarks when I get some time, but have an interview tomorrow and would like to have the answer handy for that one.
Well you should run the benchmarks you plan to, but you can guesstimate an answer.
An implementation of containsObject: might iterate calling isEqual: on each member; while an implementation of objectsPassingTest: might iterate, call the block on each member, and the block calls isEqual:...
I think you can guesstimate based on that. Have a good interview, though if the interviewer reads SO...
Even I have problems with this kind of Qs on SO, I will (partially) answer to it. And I do not think that the interviewer will get the final result, but your thoughts on it.
Both do a check with -isEqual:. But -containsObject: can do it directly, while -objectPassingTest: has to call a block.This might not be expensive, but since the code to execute is not expensive, too, this might cause a performance impact.
Beside this -containsObject: can use hashing to find an object. -objectPassingTest: in NSSet cannot, since it has no idea of what the test is. The block cannot do this neither, because he gets the objects one by one.
However, if you have mutable objects in the set, what object of custom classes are typically, no hashing can be done, because it is impossible to implement useful hashing on mutable objects in a collection.
So my estimation: Having immutable objects with a properly implemented -hash, -containsObject: will beat -objectPassingTest: by far, otherwise not that much.

When can I not use atomic properties? [duplicate]

This question already has answers here:
What's the difference between the atomic and nonatomic attributes?
(27 answers)
Closed 7 years ago.
I know there are answers on atomic vs. non-atomic answers, but they mostly seem to be fairly old (2011 and earlier), so I'm hoping for updated advice. My understanding is that non-atomic properties are faster but not thread safe. Does this mean that any property that might be accessed from multiple threads at the same time should always be atomic? Are there conditions that can make it ok to make it non-atomic? What other concerns are there in determining whether to make a property atomic or nonatomic?
Declaring a property atomic makes compiler generate additional code that prevents concurrent access to the property. This additional code locks a semaphore, then gets or sets the property, and then unlock the semaphore. Compared to setting or getting a primitive value or a pointer, locking and unlocking a semaphore is expensive (although it is usually negligible if you consider the overall flow of your app).
Since most of your classes under iOS, especially the ones related to UI, will be used in a single-threaded environment, it is safe to drop atomic (i.e. write nonatomic, because properties are atomic by default), even though the operation is relatively inexpensive, you do not want to pay for things that you do not need.
Declaring a property as atomic does not necessarily make it thread safe.
Atomic is the default and involves some extra overhead compared to nonatomic. If thread A is halfway through the getter for that property and thread B changes the value in the setter, using atomic will ensure that a viable, whole value is returned from the getter. If you use nonatomic no such guarantee is made, the extra code is not generated, and thus nonatomic is faster.
However, This does not guarantee thread safety. If thread A calls the getter and threads B and C are updating the thread with different values then thread A could get either value and there is no guarantee which one it will get.
To specifically answer your question, many scenarios allow for nonatomic properties, if not most. Although the extra overhead of using atomic is probably negligable. Simply put, are your properties read or set on different threads? If not, you most likely don't need to declare them as atomic but the extra overhead might not even be noticable. It's just that simply declaring them as atomic does not guarantee thread safety.
In most situations it is unimportant, whether a property is atomic or not in a multithreaded environment.
What?
In most situations it is unimportant, whether a property is atomic or not in a multithreaded environment.
The reason for this is that making a property "thread-safe" by turning atomicity on does not make your code thread-safe. To get this you need more work and this work typically implicitly ensures that the property is not accessed parallel.
Let's have an example: You have a class Person with the properties firstName and lastName both of NSString*. You simply want to add the both name separated with a space to have a full name.
NSString *fullName = [NSString stringWithFormat:#"%# %#", person.firstName, person.lastName];
You know that other threads can update the properties while you do that. Making the properties atomic doesn't help anything. This does not help, if the last name of the persons are changed, after reading the first name, but before reading the second name. This does not help, if the names of the persons are changed after calculating the full name, because this can be invalid in the very next moment.
You have to serialize operations, not property accesses. But atomicity only serializes accesses. So it does not help, if at least one operation has more than one access. 99,999999373 % of all cases.
Forget about property atomicity. It is meaningless.
There are no other concerns. Yes, any property that can be accessed on multiple threads should be atomic or you can end up with unexpected results.

Which is thread Safe atomic or non-atomic?

After reading this answer I am very confused.
Some says atomic is thread safe and some are saying nonatomic is thread safe.
What is the exact answer of this.
Thread unsafety of operations is caused by the fact that an operation can be divided into several suboperations, for example:
a = a + 1
can be subdivided into operations
load value of a
add 1 to the loaded value
assign the calculated value to a.
The word "Atomic" comes from "atom" which comes from greek "atomos", which means "that which can't be split". For an operation it means that it is always performed as a whole, it is never performed one suboperation at a time. That's why it is thread safe.
TL;DR Atomic = thread safe.
Big warning: Having properties atomic does not mean that a whole function/class is thread safe. Atomic properties means only that operations with the given properties are thread safe.
Obviously, nonatomic certainly isn’t thread safe. More interestingly, atomic is closer, but it is insufficient to achieve “thread safety”, as well. To quote Apple’s Programming with Objective-C: Encapsulating Data:
Note: Property atomicity is not synonymous with an object’s thread safety.
It goes on to provide an example:
Consider an XYZPerson object in which both a person’s first and last names are changed using atomic accessors from one thread. If another thread accesses both names at the same time, the atomic getter methods will return complete strings (without crashing), but there’s no guarantee that those values will be the right names relative to each other. If the first name is accessed before the change, but the last name is accessed after the change, you’ll end up with an inconsistent, mismatched pair of names.
This example is quite simple, but the problem of thread safety becomes much more complex when considered across a network of related objects. Thread safety is covered in more detail in Concurrency Programming Guide.
Also see bbum’s Objective-C: Atomic, properties, threading and/or custom setter/getter.
The reason this is so confusing is that, in fact, the atomic keyword does ensure that your access to that immediate reference is thread safe. Unfortunately, when dealing with objects, that’s rarely sufficient. First, you have no assurances that the property’s own internal properties are thread safe. Second, it doesn’t synchronize your app’s access to the object’s individual properties (such as Apple’s example above). So, atomic is almost always insufficient to achieve thread safety, so you generally have to employ some higher-level degree of synchronization. And if you provide that higher-level synchronization, adding atomicity to that mix is redundant and inefficient.
So, with objects, atomic rarely has any utility. It can be useful, though, when dealing primitive C data types (e.g. integers, booleans, floats). For example, you might have some boolean that might be updated in some other thread indicating whether that thread’s asynchronous task is completed. This is a perfect use case for atomic.
Otherwise, we generally reach for higher-level synchronization mechanisms for thread safety, such as GCD serial queues or reader-writer pattern (... or, less common nowadays, locks, the #synchronized directive, etc.).
As you can read at developer.apple you should use atomic functions for thread savety.
You can read more about atomic functions here: Atomic Man page
In short:
Atomic ~ not splittable ~ not shared by threads
As is mentioned in several answers to the posted question, atomic is thread safe. This means that getter/setter working on any thread should finish first, before any other thread can perform getter/setter.

Resources