An example of a custom nsoperation class in IOS multi-threaded application development _ios

Source: Internet
Author: User

First, to achieve a simple tableview display effect

Implementation results show:

code example (using the previous business process in the host controller)

1. Create a new project and let the controller inherit from Uitableviewcontroller.

Copy Code code as follows:

//
YYViewController.h
01-Custom Operation
//
Created by Apple on 14-6-26.
Copyright (c) 2014 itcase. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface Yyviewcontroller:uitableviewcontroller

@end


2. Processing storyboard interface, as follows:

3. According to the plist file, the dictionary turns the model

Create a new class that inherits from NSObject as a model of the data

YYappModel.h file

Copy Code code as follows:

//
YYappModel.h
01-Custom Operation
//
Created by Apple on 14-6-26.
Copyright (c) 2014 itcase. All rights reserved.
//

#import <Foundation/Foundation.h>

@interface Yyappmodel:nsobject
/**
* Application Name
*/
@property (nonatomic,copy) NSString *name;
/**
* Application Picture
*/
@property (nonatomic,copy) NSString *icon;
/**
* Download amount of Application
*/
@property (nonatomic,copy) NSString *download;

+ (Instancetype) appmodelwithdict: (Nsdictionary *) dict;
-(Instancetype) Initwithdict: (Nsdictionary *) dict;
@end


YYAPPMODEL.M file
Copy Code code as follows:

//
yyappmodel.m
01-Custom Operation
//
Created by Apple on 14-6-26.
Copyright (c) 2014 itcase. All rights reserved.
//

#import "YYappModel.h"

@implementation Yyappmodel

-(Instancetype) Initwithdict: (Nsdictionary *) dict
{
if (Self=[super init]) {
[Self setvaluesforkeyswithdictionary:dict];
}
return self;
}

Factory method
+ (Instancetype) appmodelwithdict: (Nsdictionary *) dict
{
return [[Self alloc]initwithdict:dict];
}
@end


Logical control part of the main controller, YYVIEWCONTROLLER.M file
Copy Code code as follows:

//
Yyviewcontroller.m
01-Custom Operation
//
Created by Apple on 14-6-26.
Copyright (c) 2014 itcase. All rights reserved.
//

#import "YYViewController.h"
#import "YYappModel.h"

@interface Yyviewcontroller ()
@property (Nonatomic,strong) Nsarray *apps;

@end


Copy Code code as follows:

@implementation Yyviewcontroller
#pragma mark-lazy Load
-(Nsarray *) apps
{
if (_apps==nil) {
NSString *path=[[nsbundle mainbundle]pathforresource:@ "Apps.plist" oftype:nil];
Nsarray *temparray=[nsarray Arraywithcontentsoffile:path];

Dictionary Turn model
Nsmutablearray *array=[nsmutablearray Array];
For (Nsdictionary *dict in Temparray) {
Yyappmodel *app=[yyappmodel Appmodelwithdict:dict];
[Array Addobject:app];
}
_apps=array;
}
return _apps;
}

#pragma mark-Data source method
-(Nsinteger) TableView: (UITableView *) TableView numberofrowsinsection: (nsinteger) Section
{
return self.apps.count;
}

-(UITableViewCell *) TableView: (UITableView *) TableView Cellforrowatindexpath: (Nsindexpath *) IndexPath
{
Static NSString *id=@ "ID";
UITableViewCell *cell=[tableview Dequeuereusablecellwithidentifier:id];
if (Cell==nil) {
Cell=[[uitableviewcell Alloc]initwithstyle:uitableviewcellstylesubtitle Reuseidentifier:id];
}
Yyappmodel *app=self.apps[indexpath.row];
Cell.textlabel.text=app.name;
Cell.detailtextlabel.text=app.download;

Download picture data
NSLog (@ "Load picture data---%@", [Nsthread CurrentThread]);
Nsurl *url=[nsurl URLWithString:app.icon];
NSData *data=[nsdata Datawithcontentsofurl:url];
UIImage *imgae=[uiimage Imagewithdata:data];
Cell.imageview.image=imgae;
NSLog (@ "complete display");
return cell;
}

@end


Print View:

Ii. Custom Nsoperation

Description: The above download picture data section is a very time-consuming operation, this operation task in the main thread complete, will seriously affect the user experience, resulting in UI card phenomenon. The following custom nsoperation, a new thread, lets the task that loads the picture execute asynchronously.

1. By proxy

Based on the above, create a new class that inherits from Nsoperation.

YYdownLoadOperation.h file

Copy Code code as follows:

//
YYdownLoadOperation.h
01-Custom Operation
//
Created by Apple on 14-6-26.
Copyright (c) 2014 itcase. All rights reserved.
//

#import <Foundation/Foundation.h>

#pragma mark-set agent and proxy methods
@class yydownloadoperation;
@protocol yydownloadoperationdelegate <NSObject>
-(void) Downloadoperation: (yydownloadoperation*) Operation Didfisheddownload: (UIImage *) image;
@end


Copy Code code as follows:

@interface yydownloadoperation:nsoperation
@property (nonatomic,copy) NSString *url;
@property (Nonatomic,strong) Nsindexpath *indexpath;
@property (nonatomic,strong) ID <YYdownLoadOperationDelegate> delegate;
@end

YYDOWNLOADOPERATION.M file
Copy Code code as follows:

//
Yydownloadoperation.m
01-Custom Operation
//
Created by Apple on 14-6-26.
Copyright (c) 2014 itcase. All rights reserved.
//

#import "YYdownLoadOperation.h"

@implementation Yydownloadoperation
-(void) Main
{
Nsurl *url=[nsurl URLWithString:self.url];
NSData *data=[nsdata Datawithcontentsofurl:url];
UIImage *imgae=[uiimage Imagewithdata:data];

NSLog (@ "--%@--", [Nsthread CurrentThread]);
After downloading the picture, notify the agent
if ([Self.delegate respondstoselector: @selector (downloadoperation:didfisheddownload:)]) {
Dispatch_async (Dispatch_get_main_queue (), ^{//back to the main thread, passing data to the proxy object
[Self.delegate downloadoperation:self Didfisheddownload:imgae];
});
}
}
@end


Business logic in the Master controller:
Copy Code code as follows:

//
Yyviewcontroller.m
01-Custom Operation
//
Created by Apple on 14-6-26.
Copyright (c) 2014 itcase. All rights reserved.
//

#import "YYViewController.h"
#import "YYappModel.h"
#import "YYdownLoadOperation.h"

@interface Yyviewcontroller () <YYdownLoadOperationDelegate>
@property (Nonatomic,strong) Nsarray *apps;
@property (Nonatomic,strong) Nsoperationqueue *queue;

@end


Copy Code code as follows:

@implementation Yyviewcontroller
#pragma mark-lazy load apps
-(Nsarray *) apps
{
if (_apps==nil) {
NSString *path=[[nsbundle mainbundle]pathforresource:@ "Apps.plist" oftype:nil];
Nsarray *temparray=[nsarray Arraywithcontentsoffile:path];

Dictionary Turn model
Nsmutablearray *array=[nsmutablearray Array];
For (Nsdictionary *dict in Temparray) {
Yyappmodel *app=[yyappmodel Appmodelwithdict:dict];
[Array Addobject:app];
}
_apps=array;
}
return _apps;
}

#pragma mark-lazy load queue
-(Nsoperationqueue *) queue
{
if (_queue==nil) {
_queue=[[nsoperationqueue Alloc]init];
Set the maximum concurrency number to 3
_queue.maxconcurrentoperationcount=3;
}
return _queue;
}

#pragma mark-Data source method
-(Nsinteger) TableView: (UITableView *) TableView numberofrowsinsection: (nsinteger) Section
{
return self.apps.count;
}
-(UITableViewCell *) TableView: (UITableView *) TableView Cellforrowatindexpath: (Nsindexpath *) IndexPath
{
Static NSString *id=@ "ID";
UITableViewCell *cell=[tableview Dequeuereusablecellwithidentifier:id];
if (Cell==nil) {
Cell=[[uitableviewcell Alloc]initwithstyle:uitableviewcellstylesubtitle Reuseidentifier:id];
}
Yyappmodel *app=self.apps[indexpath.row];
Cell.textlabel.text=app.name;
Cell.detailtextlabel.text=app.download;

Download picture data
NSLog (@ "Load picture data---%@", [Nsthread CurrentThread]);
Nsurl *url=[nsurl URLWithString:app.icon];
NSData *data=[nsdata Datawithcontentsofurl:url];
UIImage *imgae=[uiimage Imagewithdata:data];
Cell.imageview.image=imgae;

Create a Operation object
Yydownloadoperation *operation=[[yydownloadoperation Alloc]init];
Operation.url=app.icon;
Operation.indexpath=indexpath;
operation.delegate=self;

Add the Action object to the queue.
[Self.queue addoperation:operation];

NSLog (@ "complete display");
return cell;
}
-(void) Downloadoperation: (yydownloadoperation *) operation Didfisheddownload: (UIImage *) image
{
Returns the imageview.image of the cell corresponding to each row of the image data
Remove the cell corresponding to the Indexpath line in the TableView
UITableViewCell *cell=[self.tableview CellForRowAtIndexPath:operation.indexPath];
Show pictures
Cell.imageview.image=image;
NSLog (@ "cell--index--%@---%@", operation.indexpath,[nsthread CurrentThread]);
Be sure to refresh the table
[Self.tableview Reloaddata];
NSLog (@ "--%@--", [Nsthread CurrentThread]);

}
@end


Note: By printing you can find that the above code has a big problem.

Issue 1: You need to ensure that a URL corresponds to a Operation object.

Question 2: Remove the download. Removes the completed operation.

Question 3: Ensure that a URL corresponds to an image.
The following improvements are made to the code in the master controller:

Copy Code code as follows:

//
Yyviewcontroller.m
01-Custom Operation
//
Created by Apple on 14-6-26.
Copyright (c) 2014 itcase. All rights reserved.
//

#import "YYViewController.h"
#import "YYappModel.h"
#import "YYdownLoadOperation.h"

@interface Yyviewcontroller () <YYdownLoadOperationDelegate>
@property (Nonatomic,strong) Nsarray *apps;
@property (Nonatomic,strong) Nsoperationqueue *queue;
@property (Nonatomic,strong) nsmutabledictionary *operations;
@property (Nonatomic,strong) nsmutabledictionary *images;

@end


Copy Code code as follows:

@implementation Yyviewcontroller
#pragma mark-lazy load apps
-(Nsarray *) apps
{
if (_apps==nil) {
NSString *path=[[nsbundle mainbundle]pathforresource:@ "Apps.plist" oftype:nil];
Nsarray *temparray=[nsarray Arraywithcontentsoffile:path];

Dictionary Turn model
Nsmutablearray *array=[nsmutablearray Array];
For (Nsdictionary *dict in Temparray) {
Yyappmodel *app=[yyappmodel Appmodelwithdict:dict];
[Array Addobject:app];
}
_apps=array;
}
return _apps;
}

#pragma mark-lazy load queue
-(Nsoperationqueue *) queue
{
if (_queue==nil) {
_queue=[[nsoperationqueue Alloc]init];
Set the maximum concurrency number to 3
_queue.maxconcurrentoperationcount=3;
}
return _queue;
}

#pragma mark-lazy load operations
-(Nsmutabledictionary *) operations
{
if (_operations==nil) {
_operations=[nsmutabledictionary dictionary];
}
return _operations;
}

#pragma mark-lazy load images
-(Nsmutabledictionary *) images
{
if (_images==nil) {
_images=[nsmutabledictionary dictionary];
}
return _images;
}

#pragma mark-Data source method
-(Nsinteger) TableView: (UITableView *) TableView numberofrowsinsection: (nsinteger) Section
{
return self.apps.count;
}
-(UITableViewCell *) TableView: (UITableView *) TableView Cellforrowatindexpath: (Nsindexpath *) IndexPath
{
Static NSString *id=@ "ID";
UITableViewCell *cell=[tableview Dequeuereusablecellwithidentifier:id];
if (Cell==nil) {
Cell=[[uitableviewcell Alloc]initwithstyle:uitableviewcellstylesubtitle Reuseidentifier:id];
}
Yyappmodel *app=self.apps[indexpath.row];
Cell.textlabel.text=app.name;
Cell.detailtextlabel.text=app.download;

Ensure that a URL corresponds to an image object
UIImage *image=self.images[app.icon];
if (image) {//There is a picture in the cache
Cell.imageview.image=image;
No pictures in}else//cache, download
{
Set up a placeholder picture first
Cell.imageview.image=[uiimage imagenamed:@ "57437179_42489b0"];
Yydownloadoperation *operation=self.operations[app.icon];
if (operation) {//is downloading
Don't do anything.
}else//Not currently downloaded, create action
{
Operation=[[yydownloadoperation Alloc]init];
Operation.url=app.icon;
Operation.indexpath=indexpath;
operation.delegate=self;
[Self.queue addoperation:operation];//Asynchronous download
Self.operations[app.icon]=operation;
}
}

return cell;
}
-(void) Downloadoperation: (yydownloadoperation *) operation Didfisheddownload: (UIImage *) image
{
1. Remove the completed operation
[Self.operations RemoveObjectForKey:operation.url];

2. Put the picture in the cache
Self.images[operation.url]=image;

3. Refresh the table (refresh only the downloaded line)

[Self.tableview Reloadrowsatindexpaths:@[operation.indexpath] withrowanimation:uitableviewrowanimationautomatic] ;
NSLog (@ "--%d--%@--", Operation.indexpath.row,[nsthread CurrentThread]);

}
@end


Print View:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.