First, Nsoperation
1. Introduction
The Nsoperation instance encapsulates the required actions and the data required to perform the operation, and can perform this operation in a concurrent or non-concurrent manner.
The nsoperation itself is an abstract base class, so it must use its subclasses, and there are 2 ways to use the Nsoperation subclass:
The 1> Foundation framework provides two specific subclasses directly for our use: Nsinvocationoperation and Nsblockoperation
2> Custom subclass Inherits Nsoperation, implements the internal corresponding method
2. Perform the action
Nsoperation calls the Start method to begin the operation, and the Nsoperation object is executed synchronously by default, which is executed directly in the thread that called the Start method. The Isconcurrent method of the Nsoperation object tells us whether the operation is synchronous or asynchronous, relative to the thread that called the Start method. The Isconcurrent method returns no by default, indicating that the operation is performed synchronously with the calling thread
3. Cancel the operation
After the operation has started executing, the operation continues until it is completed, and we can call the Cancel method halfway through the operation
[Java]View Plaincopy
- [Operation Cancel];
4. Execution of the listening operation
If we want to do something after a nsoperation executes, call Nsoperation's Setcompletionblock method to set what we want to do.
[Java]View Plaincopy
- Operation.completionblock = ^ () {
- NSLog (@"execution complete");
- };
Or
[Java]View Plaincopy
- [Operation Setcompletionblock:^ () {
- NSLog (@"execution complete");
- }];
Second, nsinvocationoperation
1. Introduction
Creates an action based on an object and selector. If you already have an existing method to perform the required tasks, you can use this class
2. Create and perform actions
[Java]View Plaincopy
- This is done by calling the Run method of self
- Nsinvocationoperation *operation = [[Nsinvocationoperation alloc] initwithtarget:self selector:@selector (Run) Object:nil];
- Start task Execution (synchronous execution)
- [Operation start];
Third, nsblockoperation
1. Introduction
Ability to execute one or more block objects concurrently, after all the relevant blocks have been executed, the operation is completed
2. Create and perform actions
[Java]View Plaincopy
- Nsblockoperation *operation = [Nsblockoperation blockoperationwithblock:^ () {
- NSLog (@"performed a new operation, thread:%@", [Nsthread CurrentThread]);
- }];
- //Start a task (this is still done synchronously)
- [Operation start];
3. Adding a block operation via the Addexecutionblock method
[Java]View Plaincopy
- Nsblockoperation *operation = [Nsblockoperation blockoperationwithblock:^ () {
- NSLog (@"performing the 1th operation, Thread:%@", [Nsthread CurrentThread]);
- }];
- [Operation Addexecutionblock:^ () {
- NSLog (@"performed 1 new operations, Thread:%@", [Nsthread CurrentThread]);
- }];
- [Operation Addexecutionblock:^ () {
- NSLog (@"performed 1 new operations, Thread:%@", [Nsthread CurrentThread]);
- }];
- [Operation Addexecutionblock:^ () {
- NSLog (@"performed 1 new operations, Thread:%@", [Nsthread CurrentThread]);
- }];
- Start to perform a task
- [Operation start];
Print the following information:
[Java]View Plaincopy
- 2013-02-: 46.102 thread[4602:c07] 1 new operations were performed, Threads: <nsthread: 0x7121d50> {name = (null), num = 1}
- 2013-02-: 46.102 thread[4602:3f03] 1 new operations were performed, Threads: <nsthread: 0x742e1d0>{name = (null), num = 5}
- 2013-02-02 21:38:46.102 thread[ 4602:1b03] performing 1 operations, Threads: <nsthread: 0x742de50>{name = (null), num = 3}&NBSP;&NBSP;
- 2013-02-: 46.102 thread[4602:1303] 1 new operations were performed, thread: <nsthread: 0x7157bf0>{name = (null), num = 4}
As you can see, these 4 blocks are executed concurrently, that is, executed in different threads, and the NUM attribute can be seen as the ID of the thread.
Iv. Custom Nsoperation
1. Introduction
If the nsinvocationoperation and Nsblockoperation objects do not meet the requirements, you can directly inherit the nsoperation and add any behavior you want. The amount of work required for inheritance depends primarily on whether you want to implement non-concurrency or concurrency nsoperation. It is much simpler to define non-concurrent nsoperation, only the overloaded-(void) Main method, which executes the main task in this method and responds correctly to the cancellation event; For concurrent nsoperation, you have to rewrite the nsoperation of the basic methods to implement (here, for the time being the non-concurrent nsoperation)
2. Non-concurrent Nsoperation
For example, called downloadoperation, used to download images
1> inherits Nsoperation, overrides Main method, executive Director
DownloadOperation.h
[Java]View Plaincopy
- #Import <Foundation/Foundation.h>
- @protocol downloadoperationdelegate;
- @interface downloadoperation:nsoperation
- URL path of the picture
- @property (nonatomic, copy) NSString *imageurl;
- Agent
- @property (nonatomic, retain) id<downloadoperationdelegate> delegate;
- -(ID) Initwithurl: (nsstring *) URL delegate: (id<downloadoperationdelegate>) delegate;
- @end
- Agreement for picture Download
- @protocol downloadoperationdelegate <NSObject>
- -(void) Downloadfinishwithimage: (UIImage *) image;
- @end
Downloadoperation.m
[Java]View Plaincopy
- #Import "DownloadOperation.h"
- @implementation Downloadoperation
- @synthesize delegate = _delegate;
- @synthesize imageUrl = _imageurl;
- Initialization
- -(ID) Initwithurl: (nsstring *) URL delegate: (id<downloadoperationdelegate>) Delegate {
- if (self = [Super init]) {
- Self.imageurl = URL;
- Self.delegate = delegate;
- }
- return self;
- }
- Freeing memory
- -(void) Dealloc {
- [Super Dealloc];
- [_delegate release];
- [_imageurl release];
- }
- Executive Director Services
- -(void) Main {
- //Create a new auto-release pool, which will not be accessible to the main thread's auto-release pool If the operation is performed asynchronously
- @autoreleasepool {
- // ....
- }
- }
- @end
2> correct response to cancellation events
After operation begins execution, the task continues until it is completed, or the operation is explicitly canceled. Cancellation can occur at any time, even before operation is executed. Although Nsoperation provides a way for the application to cancel an operation, it is our own business to identify the cancellation event. If operation is terminated directly, all allocated memory or resources may not be reclaimed. So the operation object needs to detect the cancellation event and gracefully exit the execution
The Nsoperation object needs to periodically call the IsCancelled method to detect if the operation has been canceled, and if Yes is returned (indicating cancellation), exit execution immediately. Whether you are customizing the Nsoperation subclass or using the two specific subclasses provided by the system, you need to support cancellation. The IsCancelled method itself is very lightweight and can be called frequently without large performance loss
You may need to call iscancelled in the following places:
* Before any actual work is performed
* During each iteration of the loop, if each iteration is relatively long, it may need to be called multiple times
* The code is relatively easy to abort the operation anywhere
The main method of Downloadoperation is implemented as follows
[Java]View Plaincopy
- -(void) Main {
- //Create a new auto-release pool, which will not be accessible to the main thread's auto-release pool If the operation is performed asynchronously
- @autoreleasepool {
- if (self.iscancelled) return;
- //Get Picture data
- Nsurl *url = [Nsurl URLWITHSTRING:SELF.IMAGEURL];
- NSData *imagedata = [NSData Datawithcontentsofurl:url];
- if (self.iscancelled) {
- url = nil;
- ImageData = nil;
- return;
- }
- //Initialize picture
- UIImage *image = [UIImage imagewithdata:imagedata];
- if (self.iscancelled) {
- image = Nil;
- return;
- }
- if ([self.delegate respondstoselector:@selector (downloadfinishwithimage:)]) {
- //Transfer the image data back to the main thread
- [(NSObject *) self.delegate performselectoronmainthread:@selector (downloadfinishwithimage:) withobject:image Waituntildone:no];
- }
- }
- }
Multithreaded Programming 2-nsoperation