首页 > 代码库 > [IOS多线程]的使用:防止进行HTTP数据请求时,UI卡死。
[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;@endUIActivityIndicatorView* activityIndicatorView;@implementation DownloadViewController-(void)downloadImage:(NSString *) url{ NSData *data =http://www.mamicode.com/ [[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
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。