NSoperationマルチスレッドを使用した画像データの非同期ロード


NSoperationはiosパッケージ化されたマルチスレッドを実現する簡単な方法である.
ImageDownloaderを定義します.このクラスはNSOperationを継承します.同時性が必要なため、次の4つの方法を実装する必要があります.
//同時実行を許可するかどうか、
-(BOOL)isConcurrent ;
-(BOOL)isExecuting;
//完了したかどうか、これはリロードしなければなりません.そうしないと、NSOperationQueueに置かれているNSOpertaionは正常に解放されません.
- (BOOL)isFinished
//具体的なダウンロード方法はこちらで行います.
- (void)start 
 
非同時対応の場合はmainメソッドをリロードするだけでよい.ヘッダファイル
ImageDownloader.h
は、以下のように定義される.
#import <Foundation/Foundation.h>

@protocol imageDownloaderDelegate;

@interface ImageDownloader : NSOperation 
{
    NSURLRequest* _request;
    
    NSURLConnection* _connection;
    
    NSMutableData* _data;// 
    
    BOOL _isFinished; 
    
    id<imageDownloaderDelegate> delegate;
    
    NSObject *delPara;// 
}

- (id)initWithURLString:(NSString *)url;

@property (readonly) NSData *data;
@property(nonatomic, assign) id<imageDownloaderDelegate> delegate;
@property(nonatomic, retain) NSObject *delPara;

@end

@protocol imageDownloaderDelegate

@optional

// 
- (void)imageDidFinished:(UIImage *)image para:(NSObject *)obj;

@end

インプリメンテーションファイル
ImageDownloader.m
は、以下のように定義される.
#import "ImageDownloader.h"

@implementation ImageDownloader

@synthesize data=_data;
@synthesize delegate;
@synthesize delPara;

- (void)dealloc 
{
    
    [_request release]; 
    _request=nil;
    
    [_data release];
    _data=nil;
    
    [_connection release];
    _connection=nil;
    
    [delPara release];
    
    [super dealloc];
    
}
- (id)initWithURLString:(NSString *)url 
{
    
    self = [self init];
    if (self) {

        _request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
        
        _data = [[NSMutableData data] retain];
        
    }
    
    return self;
    
}



//  - 

- (void)start {
    
    if (![self isCancelled]) {
        
        [NSThread sleepForTimeInterval:3];
        //  , 
        
        _connection=[[NSURLConnection connectionWithRequest:_request delegate:self]retain];
        
        while(_connection != nil) {
            
            [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];   
            
        }
        
    }
    
}

#pragma mark NSURLConnection delegate Method

//  ( ) 

- (void)connection:(NSURLConnection*)connection

    didReceiveData:(NSData*)data 
{
    //  
    [_data appendData:data];
    
}

- (void)connectionDidFinishLoading:(NSURLConnection*)connection {
    
    [_connection release],
    _connection=nil;
    NSLog(@"%s", __func__);
    
    UIImage *img = [[[UIImage alloc] initWithData:self.data] autorelease];
    
    if (self.delegate != nil)
    {
        [delegate imageDidFinished:img para:self.delPara];
    }
    
    
}

-(void)connection: (NSURLConnection *) connection didFailWithError: (NSError *) error
{
    [_connection release],
    _connection=nil; 
}

-(BOOL)isConcurrent 
{
    // yes , 
    return YES;
    
}
- (BOOL)isExecuting
{
    return _connection == nil; 
}
- (BOOL)isFinished
{
    return _connection == nil;  
}

応用例:NSString*url=@“xxxxxx”;
NSString*param=@"追加パラメータ";ImageDownloader*downloader=[[ImageDownloader alloc]initWithURLString:url]autorelease];downloader.delegate=self;downloader.delPara=param;NSOperationQueue*queue=[[NSOperationQueue alloc]init]autorelease];
      [queue addOperation:downloader];
#pragma delegate-(void)imageDidFinished:(UIImage*)image para:(NSObject*)obj{//image、ダウンロードした画像;NSString*param=(NSString*)obj;//付属のパラメータ;}