what is nsoperation?how to use it? - objective-c

I am implementing the contact module basically adding,deleting,searching and listing the contacts.
Here i used file to persist the data like storing all the contacts in file(json format) and deserializing back to the object.
Now my target is to perform serialization and deserialization functions in background thread using nsoperation.And how one class extends nsopertions and what to do in that class.
I am new to mac os.And i cant understand what exactly nsoperation means?how to use it in my module.how to make them run concurrently.I had seen lot of tutorials but still it is very clumsy for me.I am really in need of help.Thanks in advance.

We have lot of answer to your question
What is NSOperation?
First Apple Reference Says
The NSOperation class is an abstract class you use to encapsulate the
code and data associated with a single task. Because it is abstract,
you do not use this class directly but instead subclass or use one of
the system-defined subclasses (NSInvocationOperation or
BlockOperation) to perform the actual task. Despite being abstract,
the base implementation of NSOperation does include significant logic
to coordinate the safe execution of your task. The presence of this
built-in logic allows you to focus on the actual implementation of
your task, rather than on the glue code needed to ensure it works
correctly with other system objects.
Then Simple meaning of NSOperation
NSOperation represents a single unit of work. It’s an abstract class
that offers a useful, thread-safe structure for modeling state,
priority, dependencies, and management.
Do you need to run it concurrently?
What is Concurrency?
Doing multiple things at the same time.
Taking advantage of number of cores available in multicore CPUs.
Running multiple programs in parallel.
Why NSOperationQueue?
For situations where NSOperation doesn’t make sense to build out a
custom NSOperation subclass, Foundation provides the concrete
implementations NSBlockOperation and NSInvocationOperation.
Examples of tasks that lend themselves well to NSOperation include
network requests, image resizing, text processing, or any other
repeatable, structured, long-running task that produces associated
state or data.
But simply wrapping computation into an object doesn’t do much without
a little oversight. That’s where NSOperationQueue comes in
What is NSOperationQueue?
NSOperationQueue regulates the concurrent execution of operations. It
acts as a priority queue, such that operations are executed in a
roughly First-In-First-Out manner, with higher-priority
(NSOperation.queuePriority) ones getting to jump ahead of
lower-priority ones. NSOperationQueue can also limit the maximum
number of concurrent operations to be executed at any given moment,
using the maxConcurrentOperationCount property.
NSOperationQueue itself is backed by a Grand Central Dispatch queue,
though that’s a private implementation detail.
To kick off an NSOperation, either call start, or add it to an
NSOperationQueue, to have it start once it reaches the front of the
queue. Since so much of the benefit of NSOperation is derived from
NSOperationQueue, it’s almost always preferable to add an operation to
a queue rather than invoke start directly.
Also
Operation queues usually provide the threads used to run their
operations. In OS X v10.6 and later, operation queues use the
libdispatch library (also known as Grand Central Dispatch) to initiate
the execution of their operations. As a result, operations are always
executed on a separate thread, regardless of whether they are
designated as concurrent or non-concurrent operations
So your code should be
NSOperationQueue *backgroundQueue = [[NSOperationQueue alloc] init];
[backgroundQueue addOperationWithBlock:^{
//Your Background Work kHere
.....
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
//Your Main Thread(UI) Work Here
....
}];
}];

Related

convert pthread to objective-c

Im trying to convert the following to objective-c code.
This is the current thread I have in C and works fine
//calling EnrollThread method on a thread in C
pthread_t thread_id;
pthread_create( &thread_id, NULL, EnrollThread, pParams );
//What the EnrollThread method structure looks like in C
void* EnrollThread( void *arg )
What my method structure looks like now that I've changed it to objective-c
-(void)enrollThreadWithParams:(LPBIOPERPARAMS)params;
Now I'm not sure how to call this objective-c method with the pthread_create call.
I've tried something like this:
pthread_create( &thread_id, NULL, [refToSelf enrollThreadWithParams:pParams], pParams );
But I believe I have it wrong. Can anyone enlighten me on why this does not work and what it is I need to do to fix it so that I can create my thread in the background? My UI is getting locked until the method finishes what it's doing.
I was thinking of also using dispatch_sync but I haven't tried that.
In objective C you don't really use pthread_create, although you can still use it, but the thread entry point needs to be a C function, so I'm not sure if this would be the best approach.
There are many options, as you can read in the Threading and Concurrency documents.
performSelectorInBackground method of NSObject (and subclasses)
dispatch_async (not dispatch_sync as you mentioned)
NSOperation and NSOperationQueue
NSThread class
I would suggest giving it a shot to the first one, since it is the easiest, and very straightforward, also the second one is very easy because you don't have to create external objects, you just place inline the code to be executed in parallel.
The go to reference for concurrent programming is the Concurrency Programming Guide which walks you through dispatch queues (known as Grand Central Dispatch, GCD) and operation queues. Both are incredibly easy to use and offer their own respective advantages.
In their simplest forms, both of these are pretty easy to use. As others have pointed out, the process for creating a dispatch queue and then dispatching something to that queue is:
dispatch_queue_t queue = dispatch_queue_create("com.domain.app", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(queue, ^{
// something to do in the background
});
The operation queue equivalent is:
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock:^{
// something to do in the background
}];
Personally, I prefer operation queues where:
I need controlled/limited concurrency (i.e. I'm going to dispatch a bunch of things to that queue and I want them to run concurrent with respect to not only the main queue, but also with respect to each other, but I don't want more than a few of those running simultaneously). A good example would be when doing concurrent network requests, where you want them running concurrently (because you get huge performance benefit) but you generally don't want more than four of them running at any given time). With an operation queue, one can specify maxConcurrentOperationCount whereas this tougher to do with GCD.
I need fine level of control over dependencies. For example, I'm going to start operations A, B, C, D, and E, but B is dependent on A (i.e. B shouldn't start before A finishes), D is dependent upon C, and E is dependent upon both B and D finishing.
I need to enjoy concurrency on tasks that, themselves, run asynchronously. Operations offer a fine degree of control over what determines when the operation is to be declared as isFinished with the use of NSOperation subclass that uses "concurrent operations". A common example is the network operation which, if you use the delegate-based implementation, runs asynchronously, but you still want to use operations to control the flow of one to the next. The very nice networking library, AFNetworking, for example, uses operations extensively, for this reason.
On the other hand, GCD is great for simple one-off asynchronous tasks (because you can avail yourself of built-in "global queues", freeing yourself from making your own queue), serial queues for synchronizing access to some shared resource, dispatch sources like timers, signaling between threads with semaphores, etc. GCD is generally where people get started with concurrent programming in Cocoa and Cocoa Touch.
Bottom line, I personally use operation queues for application-level asynchronous operations (network queues, image processing queues, etc.), where the degree of concurrency becomes and important issue). I tend to use GCD for lower-level stuff or quick and simple stuff. GCD (with dispatch_async) is a great place to start as you dip your toe into the ocean of concurrent programming, so go for it.
There are two things I'd encourage you to be aware of, regardless of which of these two technologies you use:
First, remember that (in iOS at least) you always want to do user interface tasks on the main queue. So the common patterns are:
dispatch_async(queue, ^{
// do something slow here
// when done, update the UI and model objects on the main queue
dispatch_async(dispatch_get_main_queue(), ^{
// UI and model updates can go here
});
});
or
[queue addOperationWithBlock:^{
// do something slow here
// when done, update the UI and model objects on the main queue
[[NSOperationQueue mainQueue] addOperationWithBlock:^{
// do UI and model updates here
}];
}];
The other important issue to consider is synchronization and "thread-safety". (See the Synchronization section of the Threading Programming Guide.) You want to make sure that you don't, for example, have the main thread populating some table view while, at the same time, some background queue is changing the data used by that table view at the same time. You want to make sure that while any given thread is using some model object or other shared resource, that another thread isn't mutating it, leaving it in some inconsistent state.
There's too much to cover in the world of concurrent programming. The WWDC videos (including 2011 and 2012) offer some great background on GCD and asynchronous programming patterns, so make sure you avail yourself of that great resource.
If you already have working code, there is no reason to abandon pthreads. You should be able to use it just fine.
If, however, you want an alternative, but you want to keep your existing pthread entry point, you can do this easily enough...
dispatch_queue_t queue = dispatch_queue_create("EnrollThread", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{
EnrollThread(parms);
});

Adding an NSOperationQueue to an NSOperation

Is it safe to add an NSOperationQueue to an NSOperation, and then add this operation to another NSOperationQueue?
Here is some code to visualize what I am trying to do.
NSOperationQueue *mainQueue = [NSOperationQueue alloc] init];
// Here I declare some NSBlockOperation's, i.e. parseOperation1-2-3
// and also another operation called zipOperation, which includes
// an NSOperationQueue itself. This queue takes the processed (parsed) files
// and write them to a single zip file. Each operation's job is to write the data
// stream and add it to the zip file. After all operations are done,
// it closes the zip.
[zipOperation addDependency:parseOperation1];
[zipOperation addDependency:parseOperation2];
[zipOperation addDependency:parseOperation3];
[mainQueue addOperation:parseOperation1];
[mainQueue addOperation:parseOperation2];
[mainQueue addOperation:parseOperation3];
[mainQueue addOperation:zipOperation];
I have used this approach and have it running in live code deployed on the App Store. I haven't experienced any issues during development or in the last 2 months since the code has been live.
In my case I had a high level series of operations, some of which contained a set of sub operations. Rather than expose the detail of each sub operation into the high level code, I created NSOperations which themselves contained NSOperationQueues and enqueued their own sub operations. The code I ended up with was much cleaner and easier to maintain.
I read extensively into NSOperation and have not seen any commentary that warns against this approach. I reviewed a lot of information online, the Apple documentation, and WWDC videos.
The only possible "drawback" might be the added complexity of understanding and implementing a Concurrent operation. Embedding an NSOperationQueue in an NSOperation means that operation becomes Concurrent.
So that's a 'YES' from me.
Additional details about concurrent operations:
An NSOperationQueue calls the start method on a normal (non-concurrent) NSOperation and expects the operation to be finished by the time the start call returns. For instance some piece of code you supplied to NSBlockOperation is complete at the end of the block.
If the work will not be finished by the time the start call returns then you configure the NSOperation as a Concurrent operation, so the NSOperationQueue knows that it has to wait until you tell it that the operation is finished at some later point in time.
For example, concurrent operations are often used to run asynchronous network calls; the start method only starts the network call, which then runs in the background, and calls back to the operation when its finished. You then change the isFinished property of the NSOperation to flag that the work is now complete.
So.... Normally when you add operations to an NSOperationQueue that queue runs those operations in the background. So if you put an NSOperationQueue inside an NSOperation then that operations work will be done in the background. Therefore the operation is concurrent and you need to flag when the internal NSOperationQueue has finished processing all it's operations.
Alternatively there are some methods on NSOperationQueue such as waitUntilAllOperationsAreFinished which could be used to ensure all the work was done before the start call returns, however these involve blocking threads and I avoided them, you may feel more comfortable with that approach, and making sure you don't have any side effects from blocking threads.
In my case I was already familiar with Concurrent operations so it was straightforward just to set it up as a Concurrent operation.
Some documentation about concurrent operations:
Concurrency Programming Guide: Configuring Operations for Concurrent Execution
In this example they are detaching a thread to perform work in the background, in our case we would be starting the NSOperationQueue here.

NSOperationQueue designated thread

I want to use an NSOperationQueue to dispatch CoreData operations. However, operation queue behavior is not always the same (e.g. it dispatches using libdispatch on iOS 4.0/OS 10.6 which uses thread pools) and a queue might not always use the same thread (as NSManagedObjectContext requires).
Can I force a serial NSOperationQueue to execute on a single thread?
Or do I have to create my own simple queuing mechanism for that?
Can I force a serial NSOperationQueue to execute on a single thread?
Or do I have to create my own simple queuing mechanism for that?
You shouldn't need to do either of those. What Core Data really requires is that you don't have two pieces of code making changes to a managed object context at the same time. There's even a note on this at the very beginning of Concurrency with Core Data:
Note: You can use threads, serial operation queues, or dispatch queues for concurrency.
For the sake of conciseness, this article uses “thread” throughout to refer to any of these.
What's really required is that you serialize operations on a given context. That happens naturally if you use a single thread, but NSOperationQueue also serializes its operations if you set maxConcurrentOperationCount to 1, so you don't have to worry about ensuring that all operations take place on the same thread.
Apple decided to bind managed objects to real Threads.. it isnt that safe anymore to access a context on different threads - a context without any objects MIGHT be safe but its objects are not

AFHTTPClient - Parsing response object

I just started using AFNetworking and I'm trying to learn how to do it correctly.
I subclass the AFHTTPClient and created my own MyAppClient with the right base URL.
I'm communicating with my server with HTTP POST request and server response with xml.
for sending a request I do:
[[MyAppClient sharedClient] postPath:somePath parameters:nil success:^(AFHTTPRequestOperation *operation, id responseObject) {
// need to parse the data here...
} failure:^(AFHTTPRequestOperation *operation, NSError *error) {
//
NSLog(#"%#", [error localizedDescription]);
}];
Few questions:
Why does the AFHTTPClient use operation if anyway it's using an asynchronous NSURLConnection that doesn't block the main thread?
After I'm getting the data I need to parse it, should I now create a new operation to parse the data?
It seems to me that it would be better to parse the data also in the operation and then return the parsed objects no?
At the same subject I have a custom generic XMLParser class that gets a NSData and parse it to NSDictionary, and I would like to use it for all of the responses, how can I integrate it in the AFHTTPClient AFHTTPRequestOperation so that the response will be already parsed?
Why does the AFHTTPClient use operation if anyway it's using an asynchronous NSURLConnection that doesn't block the main thread?
This is actually an excellent question.
In fact, a viable "HTTPRequestOperation" class is not all required to subclass from NSOperation. The design of AFHTTPRequestOperation is very likely based on the "original" design introduced by an Apple engineer, "Quinn", who invented the first "reference design" with his class QHTTPOperation and provided also a number of invaluable samples - which are still highly recommended and worth to take a look. This first design subclasses a NSOperation and encapsulates a NSURLConnection object.
This design has a number of advantages:
Since it's a subclasses of NSOperation, the network request then looks like an "asynchronous operation". That means basically, the network request then has the principal methods start and cancel and has a completion handler to signal the eventual result of the request. This generic API is important for an asynchronous network operation so that it becomes a more general asynchronous operation.
Since its a class, it encapsulates all related state variables for a request. For example, the request, the response, the response data, an error (if any), and a couple more relevant state variables. The "network request object" then becomes quite handy to use, unlike the delegate approach where it starts to become difficult when more than one request should be handled in the delegate methods in one delegate object.
An NSOperation object can be queued into a NSOperationQueue. This makes it possible to define the order of the requests, and specifically any other operation, and the number of simultaneous active operations (requests) if you have many.
With NSOperation one can define more or less complex dependencies among other operations, which lets you add some additional layer of "business logic". Occasionally, this becomes quite handy to solve more complex asynchronous problems.
So, the question why an already asynchronous NSURLConnection was encapsulated in a subclass of NSOperation are these aforementioned advantages. The reason was never to wrap it like a synchronous function into an NSOperation so that it can be executed in a NSOperationQueue.
In fact, there is a broad misconception about this. It appears, many people think the methods of the network request operation will be executed on the execution context of the NSOperation (for example when added to a NSOperationQueue). However, this is not the case (with possible small exceptions among the various other implementations). The execution context of the methods (mostly delegate methods of NSULRConnection) is a dedicated private thread which will be created by the NSOperation subclass. The lower level functions from the underlaying NSURLConnection also execute on their private execution context (one or more threads) anyway.
Only the start method will be executed on the operation's execution context, which returns quickly. That is, if there is a queue (say dispatch queue or an NSOperationQueue) where the operation has been dispatched, only the start method executes on the queue's execution context.
The NSOperation's isFinished state however, will be deferred up to the point where the network request indeed finished. This state has important meaning for other NSOperation objects and an NSOperationQueue: it signals the queue and other operations that this request has been finished.
So, the NSOperation is less a vehicle to define the execution context of the functions of a network request, but rather a means to organize and setup relations to other operations.
After I'm getting the data I need to parse it, should I now create a new operation to parse the data?
It seems to me that it would be better to parse the data also in the operation and then return the parsed objects no?
Well, you can do that. However, I wouldn't consider this a good design decision: an operation should only process a particular task. The network operation is the one, and the parse task _is another task, which can be an operation, too.
One reason for this is that operations can be "classified" regarding which system resources they mainly require: CPU, memory, IO, etc. Merging different "task types" makes it impossible to take advantage to associate them to dedicated queues in order to control utilization of system resources (see below).
Well, you can make a parse task an operation, of course. Whether this makes sense, depends, though:
The decision whether you want to make a particular task (or function) an NSOperation depends on the following considerations:
An "Operation" is justified, if that task may take a long time to finish (from a user's perspective) and thus you (as a developer) want the user give a chance to cancel the task: (you remember: an asynchronous operation has the principal method cancel)
Another reason would be to associate an operation to a particular execution context which itself is associated to a particular shared and limited system resource - like CPU, memory, IO etc. This lets you control for example the number of parallel executed operations which require a certain system resource. Say, you have a "Disk bound" task. In this case, you may create a NSOperationQueue whose number of concurrent operation is 1, and giving it a particular "role" and a suitable name, for example "DiskBoundQueue". The queue helps you control the creation and the start of operations, and forces a limit of the number of parallel executing operations so that the restricted system resource won't be exhausted. Then, one would add "disk-bound" operations only to the dedicated "DiskBoundQueue". Since a disk operates suboptimal when accessed from different tasks simultaneously, the number of concurrent operations is set to 1. That is, such dedicated queues help optimize utilization of system resources.
If you have dependencies between operations, say you want to start operation C only if operation A AND operation B has been finished successfully. NSOperation provide a means to establish such dependencies.
Yet another reason might be to control concurrent access to shared resources: if there are several operations which access a certain shared resource (an ivar for example) which are added to a serial NSOperationQueue, the access to the shared resource is serialized and thus "thread safe". However if concurrency is the only requirement, I would prefer to use the simpler approach utilizing dispatch queues and blocks.
So, and in order to be more precise regarding your question: no, an NSOperation would be likely oversized. You may be better of to use a dedicated dispatch queue, possibly a serial one which also solves concurrent access of shared resources.
At the same subject I have a custom generic XMLParser class that gets a NSData and parse it to NSDictionary, and I would like to use it for all of the responses, how can I integrate it in the AFHTTPClient AFHTTPRequestOperation so that the response will be already parsed?
A viable approach would just start the XML parser within the completion handler of a AFHTTPRequestOperation or the AFClient for example.
If you have another operation which is dependent on the XML parser's result, then one approach is to encapsulate the XML parser in an NSOperation, and then make the other operation dependent on the XML parser operation. (There are other and simpler solutions for such dependencies, though)
This doesn't immediately make sense. My guess is that using standard mechanisms provides the best performance. However, the success/failure-blocks are also executed in the operation.
I do all the parsing in the success-blocks of the operations. If you use JSON, you can also configure AFNetworking to do the de-/serialization automatically for you. You might want to convert those dictionaries and arrays into smarter classes, though.
Have a look at AFJSONRequestOperation. It might give you some hints.
1) In AFNetworking - Operation is the most granular level. You can either start it or enque them. AFHTTPClient is great if you are enqueuing requests. Look at enqueueOperation
2) AFNetworking keeps it modular. Essentially you are not tied to their parser. You can use any xml parser to parse data. Though I like (DCKeyValue)[https://github.com/dchohfi/KeyValueObjectMapping] to parse your data and directly converting them to objects.
3)You cannot automatically parse like RestKit but answer 2 should help you.

Why should I choose GCD over NSOperation and blocks for high-level applications?

Apple's Grand Central Dispatch reference says:
"...if your application needs to operate at the Unix level of the
system—for example, if it needs to manipulate file descriptors, Mach
ports, signals, or timers. GCD is not restricted to system-level
applications, but before you use it for higher-level applications, you
should consider whether similar functionality provided in Cocoa (via
NSOperation and block objects) would be easier to use or more
appropriate for your needs.".
http://developer.apple.com/library/ios/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html
I can't actually think of situations, for high-level applications, in which the use of GCD is mandatory and NSOperation could/should not be used.
Any thoughts?
The point being made here is the same one that Chris Hanson states in his article "When to use NSOperation vs. GCD":
The straightforward answer is a general guideline for all application
development:
Always use the highest-level abstraction available to you, and drop
down to lower-level abstractions when measurement shows that they are
needed.
In this particular case, it means that when writing Cocoa
applications, you should generally be using NSOperation rather than
using GCD directly. Not because of a difference in efficiency, but
because NSOperation provides a higher-level abstraction atop the
mechanisms of GCD.
In general, I agree with this. NSOperation and NSOperationQueue provide support for dependencies and one or two other things that GCD blocks and queues don't have, and they abstract away the lower-level details of how the concurrent operations are implemented. If you need that functionality, NSOperation is a very good way to go.
However, after working with both, I've found myself replacing all of my NSOperation-based code with GCD blocks and queues. I've done this for two reasons: there is significant overhead when using NSOperation for frequent actions, and I believe my code is cleaner and more descriptive when using GCD blocks.
The first reason comes from profiling in my applications, where I found that the NSOperation object allocation and deallocation process took a significant amount of CPU resources when dealing with small and frequent actions, like rendering an OpenGL ES frame to the screen. GCD blocks completely eliminated that overhead, leading to significant performance improvements.
The second reason is more subjective, but I believe that my code is cleaner when using blocks than NSOperations. The quick capture of scope allowed by a block and the inline nature of them make for less code, because you don't need to create custom NSOperation subclasses or bundle up parameters to be passed into the operation, and more descriptive code in my opinion, because you can place the code to be run in a queue at the point where it is fired off.
Again, its a matter of preference, but I've found myself using GCD more, even in otherwise more abstracted Cocoa applications.
Prefer GCD where task is not much complex and optimum CPU performance is required.
Prefer NSOperationQueue where task is complex and requires canceling or suspending a block and dependency management.
GCD is a lightweight way to represent units of work that are going to be executed concurrently. You don’t schedule these units of work; the system takes care of scheduling for you. Adding dependency among blocks can be a headache. Canceling or suspending a block creates extra work for you as a developer!
NSOperation and NSOperationQueue add a little extra overhead compared to GCD, but you can add dependency among various operations. You can re-use, cancel or suspend operations. NSOperation is compatible with Key-Value Observation (KVO); for example, you can have an NSOperation start running by listening to NSNotificationCenter.
For detailed explanation, refer this question: NSOperation vs Grand Central Dispatch
Well, NSOperation has no equivalents to dispatch_source_t, dispatch_io, dispatch_data_t, dispatch_semaphore_t, etc... It's also somewhat higher overhead.
On the flip side, libdispatch has no equivalents to operation dependencies, operation priorities (queue priorities are somewhat different), or KVO on operations.
There are two things that NSOperationQueue can do that GCD doesn't do: The minor one is dependencies (add an operation to a queue but tell it to only execute when certain other operations are finished), and the big one is that NSOperation gives you an object which can receive messages while the task is executing, unlike GCD which has blocks that cannot receive messages except in a very limited way. You either need these two features, or you don't. If you don't, using GCD is just an awful lot easier to use.
That's why useful examples of NSOperation are always quite complex. If they were easy, you would use GCD instead. You usually create a subclass of NSOperation, which will be some significant amount of work, or use one that someone else has created.
I've actually just been reading 'round about this, and, I'm sure it will come as know surprise, opinions differ.
I can't think of a case where you'd have to use GCD over NSOperation, but that doesn't mean such a case doesn't exist. I, however, agree with a general sentiment in terms of best-practice coding:
If you have a couple tools that suit the job (and in this case, you've got NSOperation vs a GCD block), use the class with the highest level of abstraction (ie, the highest level API). Not only is it typically easier to use/less code, you'll also gain from potential future enhancements introduced to the higher level APIs.