Whats the difference between detach and non-detach thread in iPhone?
The iPhone "Threading Programming Guide" documentation says that
By default the NSThread class creates detach threads
And it also says that a Detached thread means that the thread's resources are automatically reclaimed by system when the thread exits. In the same way , how does it happen in non-detach threads?
Thank You.
Suse
This relates to the underlying pthread implementation. Read up on pthread_detach and pthread_join to understand the differences.
In practice, you probably don't care and Cocoa/NSThread do the right thing for you automatically.
And to clarify, there's no way to create a non-detached thread using NSThread. You'd have to use the low-level thread API for that.
Related
I have used detachNewThreadSelector method to create threads in my app. At some point of time, when user is logged out from the app, I should kill all running threads in the app. How can I achieve it?
If you create a thread with detachNewThreadSelector you pretty much have to let it finish by itself :(
A better option if you want to be able to control background tasks would be NSOperationQueue - with this you can pass cancel messages to operations.
(Apple docs here)
EDIT : If you don't want to use NSNotificationCenter, you could set a flag that your background threads periodically check and if it's set they will exit themselves. However, you would have to be careful about thread safety there :)
Use "normal" NSThread constructor - (id)initWithTarget:... and save your thread object.
Or save thread objects somewhere after thread start.
Don't save thread objects at all, just use some separate flags that you'll check in your threads and exit them.
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!
Is there any way I can kill a thread spawn through:
[NSThread detachNewThreadSelector:#selector(serverFetchInThread) toTarget:self withObject:nil];
The scenario I am working on is that in my main thread I am letting user enter data in my search bar and what ever user is typing I need to send to server for searching in a separate thread. Now, if user changes his selection by deleting old data and entering new data I do not want the previous thread to waste its time, kill it and spawn a new thread with new data.
Be there any other better way to handle this situation, please guide me.
No, there is no way to kill a thread from another thread. And for good reason as there is no way to do so in a fashion where the targeted thread is killed without risk of crashing the app.
To directly answer your question; you need to have some kind of a flag that indicates to the thread that it should stop doing whatever it is doing and exit.
However, a couple of questions are raised by your question:
First, why are you using threads and not using GCD? Concurrency via GCD or NSOperation is the generally recommended way to solve such problems.
Secondly, if you are talking to a server, are you using HTTP (most of the time, that is the case)? If so, why not directly use the asynchronous features of NSURL and friends?
Have a good look at using NSOperationQueue.
You can subclass NSOperation it to wrap up your server communications, and even make that queue serial (maximum operations = 1).
If a server operation is not yet finished and user has generated more input, you can cancel the existing one, and add the new one.
Due to the effect of the NSOperation wrapping your connection, you can just use the simple synchronous version and keep the connection handling very straightforward.
Also worth mentioning is compatibility. I would prefer to use GCD and blocks, but for compatibility, NSOperationQueue is required.
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
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.