What is meant by CoreData is not thread safe? - iphone

In Obj-C, what does it mean in simple terms;
"CoreData is not thread safe"
OR in general what is "not thread safe" ?

#d11wtq's answer is correct only when writing your own code or designing your own APIs.
It is entirely incorrect when working with a set of APIs and quite specifically wrong when working with Core Data.
In the context of working with Mac OS X and iOS, thread safety must always be considered in the context of working with the system APIs. Even using, say, an NSArray means that you are working with the system APIs.
OR in general what is "not thread
safe" ?
A non-thread safe API is an API where you cannot interact with the API from multiple threads simultaneously. There may also be additional restrictions that most often involve the main thread. For example, almost all drawing operations must occur on the main thread on both Mac OS X and iOS.
The Apple documentation assumes thread safety is the exceptional case. That is, an API is only thread safe if the documentation explicitly claims thread safety. If there is no mention of thread safety, you must assume that the API is not thread safe.
In Obj-C, what does it mean in simple
terms; "CoreData is not thread safe"
That statement is not quite correct, but it is a safe assumption.
In Core Data's case, the thread interaction behavior is extremely well documented.
In short, parts of the API are thread safe (the store coordinator, for example) and parts are quite explicitly not thread safe. While the MOC provides lock and unlock methods, you can also use external locking. But don't. It will be less efficient and more fragile; significantly so. In general, don't use the internal locking either. CoreData is optimized around having a context per thread/queue.
(Answer fixed based on TC's feedback. Thanks.)

UPDATE | Please see #bbum's answer. I accept that my answer is flawed and #bbum is correct.
If something is described as "not thread safe", it means that no special precautions have been taken to ensure it won't crash should two separate threads try to use it simultaneously. In general, code that is to be used by more than one thread requires explicit locks (or #synchronize blocks) wrapping around aspects of the code. In particular, any object/variable that will be modified would almost certainly cause a crash if two threads happened to write to it at the same time (since they'd be writing to the same memory address). Similarly, if one thread was reading a variable while another was writing to it, garbage would be returned and the program would likely crash.
Using #synchronized, or NSLock or a POSIX mutex etc, ensures that only one thread can execute a particular block of code at any given time. The other threads get blocked and have to wait until the lock is released. There is a slight performance hit with using locks (and of course some development overhead having to think about them), so often code expressly declares that it is not thread safe, leaving you, the adopter of the code, to place locks as needed yourself (or limit execution of the non thread-safe to a single thread).
See the Apple documentation for more information about threading and thread safety:
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/ObjectiveC/Articles/ocThreading.html#//apple_ref/doc/uid/TP30001163-CH19-BCIIGGHG

Related

In what scenario does the TCAs lack of thread safety cause issues?

I’m trying to wrap my head around threading and how it affects The Composable Architecture.
I know that Store is not threadsafe and that interactions with it, such as sending an action from an effect, must be done on the main thread.
My question is why? In what scenario could sending an action on a background thread cause problems?
Further, for effects, why couldn’t the architecture call .recieve(on:) internally as opposed to me having to do it on the outside? Does this indicate that there are scenarios where background threads are acceptable?

Should iPhone app need be thread safe?

I don't use thread explicitly, so when designing an iPhone app, e.g. using Singleton, should I need to take care of the thread issue?
Beware of a singleton being called by or using any OS classes that could become multi-threaded on future multi-core hardware. Also beware of forgetting that this class isn't thread safe N years from now, reusing it, and wasting your life hunting the bug.
If not, no.
In the most part you should be safe, but I would be aware that even if you don't use threads explicitly, there are many libraries in the Apple SDK that have asynchronous callbacks (such as HTTP requests) where you will need to synchronize access across shared memory.
I hope this helps!

iPhone multi-threaded AddressBook manipulation

I have been using the AddressBook api of the iPhone for some time now. But doing some refactoring to improve application performance I have decided to "reuse" the ABAddressBookRef returned by AddressBookCreate because I noticed there are large performance improvements doing that. However, I am getting EXEC_BAD_ACCESS errors now randomly, and I think the reason is in this "caveat" in the iPhone reference implementation: http://developer.apple.com/iphone/library/documentation/ContactData/Conceptual/AddressBookProgrammingGuideforiPhone/300-BasicObjects/BasicObjects.html#//apple_ref/doc/uid/TP40007744-CH3-SW1
Important: Instances of ABAddressBookRef cannot be used by multiple threads. Each thread must make its own instance by calling ABAddressBookCreate.
Now, I thought that simply meant it was not thread-safe so I had to synchronise access to the API, but maybe I am wrong, and there is some other reasons multiple threads mess up the data structure?
Can someone confirm if it is indeed a thread-safe issue (so #synchronize should work) or some other issue?
Cheers
This is not a thread safety issue... there is no way for you to solve it with locks. The comment makes it pretty clear:
Important: Instances of ABAddressBookRef cannot be used by
multiple threads. Each thread must
make its own instance by calling
ABAddressBookCreate.
What you can do is create a single instance of the ABAddressBook and create a producer/consumer architecture that would manage the access to the object.
The wrapper will have a main thread which does one thing only: reads operation requests from a blocking queue, then performs the operations on the address book. All your threads will queue their operations to the single queue and the wrapper will execute those actions; if there is nothing in the queue then the wrapper will block until there is something in the queue.
This should solve the problem of not being allowed to use the ABAddressBookRef from multiple threads.

Will the system send an NSWillBecomeMultiThreadedNotification when I create POSIX threads?

I tried it, but I think this notification isn't coming. Is that the normal case?
No, this notification is sent by NSThread. If you're using ordinary pthreads, it won't be sent.
From the docs:
Protecting the Cocoa Frameworks For
multithreaded applications, Cocoa
frameworks use locks and other forms
of internal synchronization to ensure
they behave correctly. To prevent
these locks from degrading performance
in the single-threaded case, however,
Cocoa does not create them until the
application spawns its first new
thread using the NSThread class. If
you spawn threads using only POSIX
thread routines, Cocoa does not
receive the notifications it needs to
know that your application is now
multithreaded. When that happens,
operations involving the Cocoa
frameworks may destabilize or crash
your application.
To let Cocoa know that you intend to
use multiple threads, all you have to
do is spawn a single thread using the
NSThread class and let that thread
immediately exit. Your thread entry
point need not do anything. Just the
act of spawning a thread using
NSThread is enough to ensure that the
locks needed by the Cocoa frameworks
are put in place.
If you are not sure if Cocoa thinks
your application is multithreaded or
not, you can use the isMultiThreaded
method of NSThread to check.
It should also be noted that 'times have changed' since NSWillBecomeMultiThreadedNotification was added to Foundation. Multi-threaded programming is now much, much more common. It's now entirely within the realm of possibility, even likely, that you'll never see this notification posted in an app. Modern apps become multi-threaded very early in their life, possibly before any part of your code is ever executed. Also from the documentation:
If you are developing a Cocoa library,
you can register as an observer for
the
NSWillBecomeMultiThreadedNotification
if you want to be notified when the
application becomes multithreaded. You
should not rely on receiving this
notification, though, as it might be
dispatched before your library code is
ever called.
I'd use [NSThread isMultiThreaded] instead of relying on NSWillBecomeMultiThreadedNotification.

Running a socket stream in a thread

I have an application that opens a connection with 2 sockets (in and out) and I want to have them working in a thread.
The reason that I want them to be in a separate thread is that I don't want my application to freeze when I receive data, and this can happen anytime as long as the application is running.
Currently I have a class that handle also network communication and I run this class in an NSOperation, I'm not sure if it's the best solution.
I'm not very familiar with threading so guys if you could give me some help I would be very grateful.
Thanks
First, you should know that you can use the same socket to send and receive data — they're generally bi-directional. You should be able to share a reference to the same socket among multiple threads of execution.
Second, unless you'll be receiving large amounts of data and have experienced performance issues with your UI, I would delay optimizing for it. (Don't get me wrong, this is a good consideration, but premature optimization is the root of all evil, and simpler is generally better if it performs adequately.)
Third, NSOperation objects are "single-shot", meaning that once the main method completes, the operation task cannot be used again. This may or may not be conducive to your networking model. You might also look at NSThread. The fact that you already have the functionality "factored out" bodes well for your design, whatever turns out to be best.
Lastly, threading is a complex topic, but a good place to start (especially for Objective-C) is Apple's Threading Programming Guide.