[IOS多线程]的使用:防止进行HTTP数据请求时,UI卡死。

一、非多线程HTTP请求

如果不使用多线程,IOS的HTTP访问请求,以登录的模式为例,是这样:

//此为不正确的代码
//成功进行登录验证后进入到下一ViewController
-(void)presentToNextview{
    //到下一界面
}

//登录验证
-(void)loginCheck{
    //包含POST或GET请求来完成数据的验证,验证成功就跳转到下一界面
}

-(void)showindicator{
    //显示登录时转圈圈的菊花
}

//登录按钮的点击事件
-(IBAction)loginBTN:(id)sender{
    //执行的函数有:
    [self showindicator];
    [self loginCheck];
}

这样写代码的结果就是indicator菊花一到logincheck函数执行就会卡主,直到POST或GET请求完成才“卡到下一界面”。

网络不好的情况下就是类似死机状态。

 

二、多线程的实现。

1.子线程的创建:两种方法

第一种: [NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:self withObject:kURL];

第二种:NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(downloadImage:) object:kURL];

           [thread start];

差异:第一种直接方便,第二种在启动前可以对其的stack等参数配置,更具灵活性。

2.在子线程中召唤主线程做事:

        [self performSelectorOnMainThread:@selector(函数名) withObject:nil waitUntilDone:YES];

        //如果waitUntilDone参数为YES,那么当前线程会被阻拦,直到selector运行完。

3.代码简单示例一:登录

//此为多线程实现登录放UI卡死的代码
//成功进行登录验证后进入到下一ViewController
-(void)presentToNextview{
    //到下一界面
}

//登录验证
-(void)loginCheck{
    //包含POST或GET请求来完成数据的验证,验证成功就跳转到下一界面
   if(账号密码匹配){
        //召唤主线程跳转到下一界面
        [self performSelectorOnMainThread:@selector(presentToNextview) withObject:nil waitUntilDone:YES];
   }
}

-(void)showindicator{
    //显示登录时转圈圈的菊花
}

//登录按钮的点击事件
-(IBAction)loginBTN:(id)sender{
    //执行的函数有:
    [self showindicator];

    //开辟新的线程,执行需要联网耗时的函数loginCheck
    [NSThread detachNewThreadSelector:@selector(loginCheck) toTarget:self withObject:nil];
}

4.代码示例二:显示一张网上的图片,源代码:

 DownloadViewController.h

#import <UIKit/UIKit.h>
#import "FileConnection.h"
@interface DownloadViewController : UIViewController

@end

 DownloadViewController.m

#import "DownloadViewController.h"
#define kURL @"http://b.hiphotos.baidu.com/image/pic/item/32fa828ba61ea8d37ccb6e0e950a304e241f58ca.jpg"
@interface DownloadViewController ()

@property UIImageView *imageView;

@end

UIActivityIndicatorView* activityIndicatorView;

@implementation DownloadViewController

-(void)downloadImage:(NSString *) url{
    NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
    UIImage *image = [[UIImage alloc]initWithData:data];
    if(image == nil){
        NSLog(@"没有图片");
    }else{
        NSLog(@"刷新图片");
        [  activityIndicatorView stopAnimating ];//停止
        //通知主线程做事
        [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:NO];
        //如果waitUntilDone参数为YES,那么当前线程会被阻拦,直到selector运行完。
    }
}

-(void)updateUI:(UIImage*) image{
    self.imageView.image = image;
    //sleep(5);
}


-(void)showindicatior{
    activityIndicatorView = [ [ UIActivityIndicatorView  alloc ] initWithFrame:CGRectMake(250,30,30.0,30.0)];
    activityIndicatorView.activityIndicatorViewStyle= UIActivityIndicatorViewStyleGray;
    [self.view addSubview:activityIndicatorView];
    [activityIndicatorView startAnimating];//启动

}
- (void)viewDidLoad
{
    [super viewDidLoad];

    self.imageView=[[UIImageView alloc] initWithFrame:CGRectMake(10, 60, 300, 220)];
    
    [self.view addSubview:self.imageView];
    
    //显示菊花
    [self showindicatior];
    
    //开辟一个新的线程 2种方法
    [NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:self withObject:kURL];
    //NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(downloadImage:) object:kURL];
    //[thread start];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

 

 

 

 

[IOS多线程]的使用:防止进行HTTP数据请求时,UI卡死。,布布扣,bubuko.com

[IOS多线程]的使用:防止进行HTTP数据请求时,UI卡死。

上一篇:如何正确应对移动互联带来的影响


下一篇:iOS 打印日志的保存 (一)