线程和NSThread 、 NSOperation
1 使用NSThread实现打地鼠
1.1 问题
NSThread是ios提供的轻量级的多线程解决方案,但是需要自己管理线程的生命周期、线程同步等。本案例使用NSThread实现一个打地鼠的小游戏,在界面随机产生mouse(继承至UIButton),以及点击mouse消失得分等功能,如图-1所示:
图-1
1.2 方案
首先创建一个SingleViewApplication应用,在该应用中创建一个TRMouse地鼠类,由于地鼠具有点击功能,因此TRMouse类继承至UIButton。
其次在TRMouse的初始化方法中将背景设置为红色,标题设置为3,并添加点击事件当地鼠出现在界面三秒钟之内被点击即消失得分。
地鼠出现三秒钟没有被点击则自动消失,所以TRMouse类中需要使用detachNewThreadSelector:toTarget:withObject:方法开一个线程用于计时,每隔一秒调用一次refresh方法,地鼠的标题进行三、二、一倒计时显示,最后从界面消失。
然后在Storyboard的场景中拖放两个Label分别用于显示成功的计数和失败的计数,并关联成ViewController的输出口属性successLabel和failLabel。
当成功点击地鼠时成功计数加一,地鼠自动消失失败计数加一,该功能可以通过委托协议来实现,在TRMouse类中定义一个TRMouseDelegate协议,该协议有一个需要实现的方法-(void)changeScoreWithSuccess:(BOOL)isSuccess。再在TRMouse类中定义一个公开的属性id<TRMouseDelegate>delegate,用于指定委托对象。在成功点击地鼠消失方法中delegate调用changeScoreWithSuccess:方法isSuccess参数传入YES,在地鼠自动消失的方法delegate调用changeScoreWithSuccess:方法isSuccess参数传入NO。
最后在ViewController类的viewDidLoad方法中开启一个线程,用于定时调用addMouse方法产生地鼠对象,然后返回主线程将产生的地鼠对象添加到界面。
ViewController类遵守TRMouseDelegate协议,在创建TRMouse对象时将delegate指定为ViewController。ViewController实现changeScoreWithSuccess:方法,根据isSucces参数修改successLabel和failLabel的显示内容。
1.3 步骤
实现此案例需要按照如下步骤进行。
步骤一:创建地鼠类TRMouse
首先创建一个SingleViewApplication应用,在该应用中创建一个TRMouse地鼠类,由于地鼠具有点击功能,因此TRMouse类继承至UIButton,如图-2所示:
图-2
其次在TRMouse的初始化方法中将背景设置为红色,标题设置为3,并添加点击事件当地鼠出现在界面三秒钟之内被点击即消失,代码如下所示:
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
count = ;
self.backgroundColor = [UIColorredColor];
[selfsetTitle:[NSStringstringWithFormat:@"%d",count] forState:UIControlStateNormal];
[selfaddTarget:self action:@selector(clicked) forControlEvents:UIControlEventTouchUpInside];
}
return self;
}
实现clicked方法,代码如下所示: - (void)clicked {
[selfremoveFromSuperview];
self.tag = ;
}
地鼠出现三秒钟没有被点击则自动消失,所以TRMouse类中需要使用detachNewThreadSelector:toTarget:withObject:方法开一个线程用于计时,每隔一秒调用一次refresh方法,地鼠的标题进行三、二、一倒计时显示,最后从界面消失,代码如下所示: - (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
count = ;
self.backgroundColor = [UIColorredColor];
[selfsetTitle:[NSStringstringWithFormat:@"%d",count] forState:UIControlStateNormal];
[selfaddTarget:self action:@selector(clicked) forControlEvents:UIControlEventTouchUpInside];
}
[NSThreaddetachNewThreadSelector:@selector(refresh) toTarget:selfwithObject:nil];
return self;
}
//实现refresh方法
- (void)refresh {
for(inti=;i<;i++) {
[selfperformSelectorOnMainThread:@selector(mouseDisapear) withObject:nilwaitUntilDone:NO];
[NSThread sleepForTimeInterval:];
}
}
//实现mouseDisappear方法
-(void)mouseDisapear {
self.titleLabel.text =[NSStringstringWithFormat:@"%d",count];
NSLog(@"count = %d",count);
if (count==&&self.tag!=) {
[selfremoveFromSuperview];
}
count--;
}
步骤二:添加成功标签和失败标签 首先在Storyboard的场景中拖放两个Label分别用于显示成功的计数和失败的计数,并关联成ViewController的输出口属性successLabel和failLabel,代码如下所示: @interfaceViewController ()
@property (weak, nonatomic) IBOutletUILabel *successLabel;
@property (weak, nonatomic) IBOutletUILabel *failLabel;
@end
当成功点击地鼠时成功计数加一,地鼠自动消失失败计数加一,该功能可以通过委托协议来实现,在TRMouse类中定义一个TRMouseDelegate协议,该协议有一个需要实现的方法-(void)changeScoreWithSuccess:(BOOL)isSuccess,代码如下所示: @protocolTRMouseDelegate
-(void)changeScoreWithSuccess:(BOOL)isSuccess;
@end
再在TRMouse类中定义一个公开的属性id<TRMouseDelegate>delegate,用于指定委托对象,代码如下所示: @interfaceTRMouse : UIButton
@property (nonatomic,assign) id<TRMouseDelegate> delegate;
@end
最后在成功点击地鼠消失方法中delegate调用changeScoreWithSuccess:方法isSuccess参数传入YES,在地鼠自动消失的方法delegate调用changeScoreWithSuccess:方法isSuccess参数传入NO,代码如下所示: //成功点击
- (void)clicked {
[selfremoveFromSuperview];
self.tag = ;
[self.delegatechangeScoreWithSuccess:YES];
}
//失败自动消失
-(void)mouseDisapear {
self.titleLabel.text =[NSStringstringWithFormat:@"%d",count];
NSLog(@"count = %d",count);
if (count==&&self.tag!=) {
[selfremoveFromSuperview];
[self.delegatechangeScoreWithSuccess:NO];
}
count--;
}
步骤三:搭建界面 首先在ViewController类的viewDidLoad方法中开启一个线程,用于定时调用addMouse方法产生地鼠对象,然后返回主线程将产生的地鼠对象添加到界面,代码如下所示: - (void)viewDidLoad {
[superviewDidLoad];
[NSThreaddetachNewThreadSelector:@selector(addMouse) toTarget:selfwithObject:nil];
}
- (void)addMouse {
for (inti=;;i++) {
[NSThread sleepForTimeInterval:];
[selfperformSelectorOnMainThread:@selector(addMouseView) withObject:nilwaitUntilDone:NO];
}
}
- (void)addMouseView {
CGSizescreenSize = [[UIScreenmainScreen]bounds].size;
TRMouse *mouse = [[TRMousealloc]initWithFrame:CGRectMake(arc4random()%(int)(screenSize.width-), +arc4random()%(int)(screenSize.height-), , )];
[self.viewaddSubview:mouse];
}
然后ViewController类遵守TRMouseDelegate协议,在创建TRMouse对象时将delegate指定为ViewController,代码如下所示: - (void)addMouseView {
CGSizescreenSize = [[UIScreenmainScreen]bounds].size;
TRMouse *mouse = [[TRMousealloc]initWithFrame:CGRectMake(arc4random()%(int)(screenSize.width-), +arc4random()%(int)(screenSize.height-), , )];
mouse.delegate = self;
[self.viewaddSubview:mouse];
}
最后ViewController实现changeScoreWithSuccess:方法,根据isSucces参数修改successLabel和failLabel的显示内容: -(void)changeScoreWithSuccess:(BOOL)isSuccess {
switch ((int)isSuccess) {
case :{
int count = [self.failLabel.textintValue];
self.failLabel.text = [NSStringstringWithFormat:@"%d",++count];
}
break;
case :{
int count = [self.successLabel.textintValue];
self.successLabel.text = [NSStringstringWithFormat:@"%d",++count];
}
}
}
1.4 完整代码 本案例中,ViewController.m文件中的完整代码如下所示: #import "ViewController.h"
@interfaceViewController () <TRMouseDelegate>
@property (weak, nonatomic) IBOutletUILabel *successLabel;
@property (weak, nonatomic) IBOutletUILabel *failLabel;
@end
@implementationViewController
- (void)viewDidLoad {
[superviewDidLoad];
[NSThreaddetachNewThreadSelector:@selector(addMouse) toTarget:selfwithObject:nil];
}
- (void)addMouse {
for (inti=;;i++) {
[NSThread sleepForTimeInterval:];
[selfperformSelectorOnMainThread:@selector(addMouseView) withObject:nilwaitUntilDone:NO];
}
}
- (void)addMouseView {
CGSizescreenSize = [[UIScreenmainScreen]bounds].size;
TRMouse *mouse = [[TRMousealloc]initWithFrame:CGRectMake(arc4random()%(int)(screenSize.width-), +arc4random()%(int)(screenSize.height-), , )];
mouse.delegate = self;
[self.viewaddSubview:mouse];
}
-(void)changeScoreWithSuccess:(BOOL)isSuccess {
switch ((int)isSuccess) {
case :{
int count = [self.failLabel.textintValue];
self.failLabel.text = [NSStringstringWithFormat:@"%d",++count];
}
break;
case :{
int count = [self.successLabel.textintValue];
self.successLabel.text = [NSStringstringWithFormat:@"%d",++count];
}
}
}
@end 本案例中,TRMouse.h文件中的完整代码如下所示: #import<UIKit/UIKit.h>
@protocolTRMouseDelegate
-(void)changeScoreWithSuccess:(BOOL)isSuccess;
@end
@interfaceTRMouse : UIButton
@property (nonatomic,assign) id<TRMouseDelegate> delegate;
@end 本案例中,TRMouse.m文件中的完整代码如下所示: #import "TRMouse.h"
@interfaceTRMouse (){
int count;
}
@end
@implementationTRMouse
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
count = ;
self.backgroundColor = [UIColorredColor];
[selfsetTitle:[NSStringstringWithFormat:@"%d",count] forState:UIControlStateNormal];
[selfaddTarget:self action:@selector(clicked) forControlEvents:UIControlEventTouchUpInside];
}
[NSThreaddetachNewThreadSelector:@selector(refresh) toTarget:selfwithObject:nil];
return self;
}
- (void)clicked {
[selfremoveFromSuperview];
self.tag = ;
[self.delegatechangeScoreWithSuccess:YES];
}
- (void)refresh {
for(inti=;i<;i++) {
[selfperformSelectorOnMainThread:@selector(mouseDisapear) withObject:nilwaitUntilDone:NO];
[NSThread sleepForTimeInterval:];
}
}
-(void)mouseDisapear {
self.titleLabel.text =[NSStringstringWithFormat:@"%d",count];
NSLog(@"count = %d",count);
if (count==&&self.tag!=) {
[selfremoveFromSuperview];
[self.delegatechangeScoreWithSuccess:NO];
}
count--;
}
@end
线程和NSThread 、 NSOperation的更多相关文章
- 多线程技术 NSThread & NSOperation & GCD
多线程:在iOS开发中,用到多线程的处理问题的时候有很多,比如异步下载数据时刷新界面等等. 引入多线程来处理问题的关键就是,基于多线程可以使界面更加流畅,防止界面假死. 界面假死:比如你单击一个按钮来 ...
- 多线程&NSObject&NSThread&NSOperation&GCD
1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 以下两点是苹果专门开发的“并发”技术,使得程序员可以不再去关心线程的具体使用问题 2.NSOperation/NS ...
- 多线程之pthread, NSThread, NSOperation, GCD
关于多线程会有一系列如下:多线程之概念解析 多线程之pthread, NSThread, NSOperation, GCD 多线程之NSThread 多线程之NSOperation 多线程之GCD p ...
- 【学习总结】【多线程】 线程 & 进程 & NSThread(多线程的一套API)
一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开 Chrome.Xcode,系统就会分别启动2个进 ...
- iOS-多线程--(pthread/NSThread/GCD/NSOperation)--总结
零.线程的注意点(掌握) .不要同时开太多的线程(~3条线程即可,不要超过5条) .线程概念 > 主线程 : UI线程,显示.刷新UI界面,处理UI控件的事件 > 子线程 : 后台线程,异 ...
- iOS-多线程--介绍NSThread和GCD及其它们的线程通讯示例
前言:下面就不一一列出 pthread.NSThread.GCD.NSOperation 的完整的各种方法了,只分别将最常用的列出来,以便偶尔瞄一眼. 一.NSThread 1> 线程间的通讯/ ...
- iOS的三种多线程技术NSThread/NSOperation/GCD
1.iOS的三种多线程技术 1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.以下两点是苹果专门开发的"并发"技术,使得程序员可以不再去关心 ...
- iOS多线程开发--NSThread NSOperation GCD
多线程 当用户播放音频.下载资源.进行图像处理时往往希望做这些事情的时候其他操作不会被中 断或者希望这些操作过程中更加顺畅.在单线程中一个线程只能做一件事情,一件事情处理不完另一件事就不能开始,这样势 ...
- iOS 多线程 简单学习NSThread NSOperation GCD
1:首先简单介绍什么叫线程 可并发执行的,拥有最小系统资源,共享进程资源的基本调度单位. 共用堆,自有栈(官方资料说明iOS主线程栈大小为1M,其它线程为512K). 并发执行进度不可控,对非原子操作 ...
随机推荐
- 【RabbitMQ】RabbitMQ在Windows的安装和简单的使用
版本说明 使用当前版本:3.5.4 安装与启动 在官网上下载其Server二进制安装包,在Windows上的安装时简单的,与一般软件没什么区别. 安装前会提示你,还需要安装Erlang,并打开下载页面 ...
- Vsftpd 配置
步骤 本次是在CentOS 6的版本上操作的. 说明:以下命令均在root用户下执行. (1)安装vsftpd 没啥好说的一条命令搞定. $yum install vsftpd 中间会提示确认,输 ...
- CUBRID学习笔记 48查询优化
cubrid的中sql查询语法 查询优化 c#,net,cubrid,教程,学习,笔记欢迎转载 ,转载时请保留作者信息.本文版权归本人所有,如有任何问题,请与我联系wang2650@sohu.com ...
- Sprint(第六天11.19)
燃尽图
- js判断鼠标进入以及离开容器的方向
(注:以下代码涉及到jQuery,建议前端大牛绕路~~~) 1.遇到的问题 如图当鼠标右箭头位置上下移动的时候 下面的城市列表容器不能隐藏. 2.方法: 网上搜了些前端大牛们的解决办法 ...
- 《BI那点儿事》数据流转换——导入列、导出列
导入列: 导入列例子现在来做一个例子:创建路径D:\Pictures随便在路径D:\Pictures中粘贴4个比较小的图像文件命名为01.png.02.png.03.png.04.png在路径D:\P ...
- 整合Spring Data JPA与Spring MVC: 分页和排序
之前我们学习了如何使用Jpa访问关系型数据库.比较完整Spring MVC和JPA教程请见Spring Data JPA实战入门,Spring MVC实战入门. 通过Jpa大大简化了我们对数据库的开发 ...
- Linux编程之驱动
增加自己写的驱动程序:http://blog.chinaunix.net/uid-23065002-id-115739.html http://os.51cto.com/art/201108/2840 ...
- JavaScipt 源码解析 Sizzle选择器
jQuery的定位就是一个DOM的操作库,那么可想而知选择器是一个至关重要的模块.Sizzle,作为一个独立全新的选择器引擎,出现在jQuery 1.3版本之后,并被John Resig作为一个开源的 ...
- SSH原理与运用
SSH是每一台Linux电脑的标准配置. 随着Linux设备从电脑逐渐扩展到手机.外设和家用电器,SSH的使用范围也越来越广.不仅程序员离不开它,很多普通用户也每天使用. SSH具备多种功能,可以用于 ...