Can anybody give me example that NSMutableArray is thread safe or not?
It is not thread safe. See the list of thread safe/unsafe classes here
According to the Apple docs NSMutableArray is not thread safe.
Mutable objects are generally not
thread-safe. To use mutable objects in
a threaded application, the
application must synchronize access to
them using locks. (For more
information, see “Atomic Operations”).
In general, the collection classes
(for example, NSMutableArray,
NSMutableDictionary) are not
thread-safe when mutations are
concerned. That is, if one or more
threads are changing the same array,
problems can occur. You must lock
around spots where reads and writes
occur to assure thread safety.
http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/ThreadSafetySummary/ThreadSafetySummary.html
Related
While using theinversifyJS library, I saw a statement that the singleton pattern is safe because node.js is single-threaded.
How does single-threading benefit from singletons over multithreading?
It's hard to know what the author meant. One likely explanation is that a single thread can't race with itself when lazily initializing a singleton. In a multi-threaded environment, two threads could naively test whether the singleton has been initialized, then both could initialize it, meaning it's no longer truly a singleton. This could cause problems if initializing it has side effects.
Does it turn some managed objects into faults when there's a Low Memory Warning? Or must we do that manually by calling the -refreshObjects:mergeChanges: method which puts the affected managed objects on diet quickly? And...would that actually hurt? What if these objects are currently used by an NSFetchedResultsController to show up on a table view?
Yes, Core Data listens for low memory warnings and will drop its cache and attempt to fault any object that it can to reduce its memory consumption.
If the object is currently being used it would automatically realize that object the next time you accessed on of its properties so from your application's point of view, nothing has happened and no NSManagedObject entities have been released.
In the case where you have established a relationship between two objects, you MUST use the managedObjectContext method -refreshObject:mergeChanges:NO after doing a save, to tell CoreData that the related object can be released. I think of it as the moral equivalent to a [object release]; statement; you are telling CoreData to release the object it read it from the DB. The tradeoff, as Marcus says, is that it will be released from memory cache, but have to be read back in by core data. the good news is that it happens behind the scenes and you don't have to program for it; the bad news is that it happens behind the scenes and thus can 'magically' chew up memory.
Ways around it are many; for example, use a predicate to only select the rows you absolutely must need; don't do a general call to fetch everything and then go through the list one by one. More than likely you will crash when you do the general call and CoreData attempts to load all objects.
I have a custom model class with an NSMutableData ivar that will be accessed by custom NSOperation subclasses (using an NSOperationQueue). I think I can guarantee thread-safe access to the ivar from multiple NSOperations by using dependencies, and I can guarantee that I don't access the ivar from other code (say my main app thread) by waiting until the Q has finished all operations.
Should I use a nonatomic property specification, or leave it atomic? Is there a significant impact on performance?
Andrew, whether it's significant depends on what you are doing. If your Operations are uploading movies to youtube and each operation needs to read the data once then it doesn't make the slightest bit of difference - just leave it as atomic.
Otherwise you need to profile to see if it is significant. If you are sure (you don't sound that sure) that the NSMutableData will never be accessed from two or more threads simultaneously (however you do it, lock, barriers, or just waiting) then you don't have a need for it to be atomic.
Premature optimisation is the root of all evil.
Leave it atomic until you find out for sure that there is a performance issue.
If it's a mutable object then your biggest enemy is concurrent mutation, not inconsistent property access.
The docs say that I should not release any modeled property in -dealloc. For me, that feels like violating the big memory management rules. I see a big retain in the header and no -release, because Core Data seems to do it at any other time.
Is it because Core Data may drop the value of a property dynamically, at any time when needed? And what's Core Data doing when dropping an managed object? If there's no -dealloc, then how and when are the properties getting freed up?
Core Data has NSManagedObjects as their base object, they are managed by the system and you do not have to do any memory managment on them...well unless u declare your own properties in a class that are not defined in the object model...
The tricky bit of managed object memory comes when the objects are turned into faults. A fault is a ghost of the object. It exists and responds to messages but it doesn't have it's attributes populated. For example, you can count the number of objects in a to-many relationship even if the objects themselves are faults.
Faults are used to maintain the object graph in memory without the overhead of the actual data. The object is still technically alive so its dealloc has never been called.
When the context turns an object into a fault, the object releases and nils it's attributes in memory. It does this in willTurnIntoFault and didTurnIntoFault. If you need to do some special releasing you should override those methods (usually the latter.)
Faulting makes managed objects rely on different methods than other classes for intialization and clean up. You intialize in awakeFromInsert or awakeFromFetch and you dealloc in willTurnIntoFault and didTurnIntoFault.
It's important to follow the rules for managed objects because the context might keep thousands of faulted objects in memory. If you create a custom attribute but do not release it when the object becomes a fault, then you could easily tie up a large amount of memory accidentally.
I'm passing some NSManagedObject data between two threads using NSOperationQueue with concurrency level to max of 1 and I'd like some suggestions on whether I'm doing this correctly.
Since NSManagedObject is not thread-safe, I'm sending in the NSManagedObjectID from ThreadA (main thread) to ThreadB via an NSOperation derived class. The general work flow:
ThreadA (main thread):
creates NSPersistentStoreCoordinator
creates main NSManagedObjectContext(1)
creates NSManagedObjectContext(2) for use in workerThread
creates MyNSOperationItem, passes along NSManagedObjectContext and adds MyNSOperationItem to NSOperationQueue
ThreadB (NSOperationQueue's thread):
NSOperation derived class will retrieve data from the persistent
store using the supplied objectID.
My NSOperation class looks like this:
#interface MyNSOperationItem: NSOperation
{
// MyNSOperationItem is created in thread1 and MOC will be
// set on creation
NSManagedObjectContext *threadedMOC;
NSManagedObjectID *workItemObjectID;
}
#end
So is it okay for my NSOperation derived class to have a reference to NSManagedObjectContext or should I store the second NSManagedObjectContext elsewhere? Since this is a queue, numerous instances of MyNSOperationItem will have been created, each of them pointing to the same NSManagedObjectContext.
I think this should give you all you need:
http://developer.apple.com/mac/libra...reData/Articles/cdMultiThreading.html
If you need to offload the fetch to a background thread, here is a little tip from the document I referenced above:
Fetching in a Background Thread
One of the simplest multi-threading
techniques you can use with Core Data
to improve application responsiveness
is to execute a fetch request on a
background thread. (Note that this
technique is only useful if you are
using an SQLite store, since data from
binary and XML stores is read into
memory immediately on open.) This
means that if a fetch is complicated
or returns a large amount of data, you
can return control to the user and
display results as they arrive. For an
example of how to do this, see the
BackgroundFetching example in
/Developer/Examples/CoreData/.
You use two managed object contexts
associated with a single persistent
store coordinator. You fetch in one
managed object context on a background
thread, and pass the object IDs of the
fetched objects to another thread. In
the second thread (typically the
application's main thread, so that you
can then display the results), you use
the second context to fault in objects
with those object IDs (you use
objectWithID: to instantiate the
object).