ios多线程操作(三)—— 线程通讯
来源:互联网 发布:js获取系统当前日期 编辑:程序博客网 时间:2024/05/19 09:49
一个进程中,线程并非单独存在,往往需要与其他线程进行通讯以执行特定的任务。接下来就用一个简单的例子来实现线程之间最简单的通讯,并借此探究一下UI控件下得常见设置
需求:从网络上下载一张图片在屏幕上显示,图片可以滚动,可以捏合缩放大小
效果如下:
开始图片没有显示是因为正在从网上下载
项目开搞
新建一个新项目。
因为视图有滚动的需求,所以需要添加一个UIScrollView以及一个显示图片的UIImageView
@interface ViewController () <UIScrollViewDelegate>@property (nonatomic,strong) UIScrollView *scrollView;@property (weak,nonatomic) UIImageView *imgV;@end
在loadView方法里面初始化UI控件,将scrollView设为根视图
- (void)loadView{ _scrollView = [[UIScrollView alloc] init]; self.view = _scrollView; self.view.backgroundColor = [UIColor brownColor]; // 初始化UIImageView UIImageView *imgV = [[UIImageView alloc] init]; [self.view addSubview:imgV]; self.imgV = imgV;}
设置scrollView的代理,图片的缩放操作将由代理的方法来实现,在后台开启一条线程执行下载图片的耗时操作:
- (void)viewDidLoad { [super viewDidLoad]; _scrollView.delegate = self; // 最小缩放比例 _scrollView.minimumZoomScale = 0.5; // 最大缩放比例 _scrollView.maximumZoomScale = 2.0; // 在后台开启一条线程执行下载图片的耗时操作 [self performSelectorInBackground:@selector(downloadImage) withObject:nil]; // 打印所在线程 NSLog(@"viewDidLoad - %@",[NSThread currentThread]);}
将下载图片抽取为一个方法downloadImage,该方法中实现了线程间的通信 ———— 让主线程更新UI,通知主线程区执行setImage:方法,通讯对象是从网络上下载的image图片对象
- (void)downloadImage{ NSURL *url = [NSURL URLWithString:@"http://g.hiphotos.baidu.com/image/pic/item/4afbfbedab64034f06bd8359acc379310a551d78.jpg"]; NSData *data = [NSData dataWithContentsOfURL:url]; UIImage *image = [UIImage imageWithData:data]; // 更新UI都要在主线程执行 [self performSelectorOnMainThread:@selector(setImg:) withObject:image waitUntilDone:NO]; NSLog(@"downloadImage - %@",[NSThread currentThread]);}
在setImg:方法里面让图片显示
- (void)setImg:(UIImage *)img{ self.imgV.image = img; // 设置UIImageView根据image自动调节frame的大小 [self.imgV sizeToFit]; // 设置scrollView滚动范围 self.scrollView.contentSize = img.size; NSLog(@"setImg - %@",[NSThread currentThread]);}
代理方法:
/** * 该方法返回需要缩放的view */- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{ return self.imgV;}
如此这般就简单实现了线程间的通讯,程序会从网络上下载图片显示,控制台打印的结果如下
number = 1 代表在主线程上执行。
number = 2(只要number!=1)代表在子线程上执行。
耗时操作在后台子线程执行,更新UI在主线程执行。
为何在后台子线程执行,如果在主线程执行耗时操作,那么该操作执行期间,主线程一直被占用,用户的操作就无法响应,这样的后果可想而知。
为什么更新UI要在主线程执行?在子线程中是不能进行UI 更新的,而可以更新的结果只是一个幻像:因为子线程代码执行完毕了,又自动进入到了主线程,执行了子线程中的UI更新的函数栈,这中间的时间非常的短,就让大家误以为分线程可以更新UI。如果子线程一直在运行,则子线程中的UI更新的函数栈 主线程无法获知,即无法更新。只有极少数的UI能更新,因为开辟线程时会获取当前环境,如点击某个按钮,这个按钮响应的方法是开辟一个子线程,在子线程中对该按钮进行UI 更新是能及时的,如换标题,换背景图,但这没有任何意义。
0 1
- ios多线程操作(三)—— 线程通讯
- ios多线程操作(三)—— 线程通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- 多线程编程之三——线程间通讯
- tesseract在ok6410下的实现(一)
- CAS单点登录源码解析之【客户端】
- POJ Out of Hay(2395 prim最小生成树)
- Java中获取当前时间的类
- Android消息队列模型——Thread,Handler,Looper,Massage Queue
- ios多线程操作(三)—— 线程通讯
- 实心菱形
- ascii排序2, 测试通过
- linux下maven的安装
- 题目:如何判断一个机器是大端还是小端
- [译]【Storm入门指南】第六章 真实示例
- 输入两个正整数m和n,求其最大公约数和最小公倍数
- 字符串中的空格
- xxxSchedule-2-整体架构