使用NSThread创建线程

来源:互联网 发布:万能搬家软件下载 编辑:程序博客网 时间:2024/05/22 07:55

 

大家都明白,创建线程的目的就是让程序同时做多件事情,尤其是对于需要长时间执行的操作,让用户等着他完成是不科学的。一般处理模式是,与用户息息相关的界面显示使用主线程,与界面相关的信息处理及逻辑处理我们会开启另外一个线程处理,这样不妨碍用户与界面的互动。

本篇使用NSThread创建线程,来封装一个需要长时间的操作,处理完后再通知主线程刷新界面。

可以直接使用NSThread创建线程,不过这样会将所有代码放置再主线程中,耦合的有点厉害,我建议派生NSThread,将长时间操作放在派生类的main函数中。本例main函数中先睡眠10秒,再获取一张图片,完成后通知主线程。

//
//  MyThread.h
//

#import <Foundation/Foundation.h>
#import "MQLOtherViewController.h"

@interface MyThread : NSThread

@property(nonatomic, weak) MQLOtherViewController *delegate;

@end

//
//  MyThread.m
//

#define kURL @"http://avatar.csdn.net/6/0/2/3_qianlima210210.jpg"
#import "MyThread.h"

@implementation MyThread

-(void)main
{
    [self downloadImage:kURL];
}

-(void)downloadImage:(NSString *) url{
    
    NSLog(@"downloadImage = %@", self);

    sleep(10);
    NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];

    if ([self isCancelled]) {
        [NSThread exit];
        return;
    }
    UIImage *image = [[UIImage alloc]initWithData:data];
    if(image == nil){
        
    }else{
        [self.delegate performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:NO];
    }
}

@end

封装完后,我们在主线程中使用封装好的线程类:
//
//  MQLOtherViewController.h
//

#import <UIKit/UIKit.h>

@interface MQLOtherViewController : UIViewController

-(void)updateUI:(UIImage*) image;

@end

//
//  MQLOtherViewController.m
//

#import "MQLOtherViewController.h"
#import "MyThread.h"

@interface MQLOtherViewController ()

@property (nonatomic, strong) MyThread *thread;
@property (nonatomic, weak) IBOutlet UIImageView *imageview;


-(IBAction)startClicked:(id)sender;     //启动按钮的响应函数
-(IBAction)cancelClicked:(id)sender;  //取消按钮的响应函数

@end

@implementation MQLOtherViewController

-(IBAction)startClicked:(id)sender
{
    self.thread = [[MyThread alloc]init];//创建子线程
    self.thread.delegate = self;        //设置子线程的代理
    [self.thread start];                //启动子线程,start中会调用main函数,所以我将长时间操作放在了main里
}

-(IBAction)cancelClicked:(id)sender
{
    [self.thread cancel];    //取消线程,cancel并没有中止子线程,仅仅设置了取消状态,子线程应使用isCancelled判断来使用exit中止子线程
}

-(void)updateUI:(UIImage*) image{
    NSLog(@"updateUI");
    self.imageview.image = image;
}

@end

0 0