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的更多相关文章

  1. 多线程技术 NSThread & NSOperation & GCD

    多线程:在iOS开发中,用到多线程的处理问题的时候有很多,比如异步下载数据时刷新界面等等. 引入多线程来处理问题的关键就是,基于多线程可以使界面更加流畅,防止界面假死. 界面假死:比如你单击一个按钮来 ...

  2. 多线程&NSObject&NSThread&NSOperation&GCD

    1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 以下两点是苹果专门开发的“并发”技术,使得程序员可以不再去关心线程的具体使用问题 2.NSOperation/NS ...

  3. 多线程之pthread, NSThread, NSOperation, GCD

    关于多线程会有一系列如下:多线程之概念解析 多线程之pthread, NSThread, NSOperation, GCD 多线程之NSThread 多线程之NSOperation 多线程之GCD p ...

  4. 【学习总结】【多线程】 线程 & 进程 & NSThread(多线程的一套API)

    一.进程和线程 1.什么是进程 进程是指在系统中正在运行的一个应用程序 每个进程之间是独立的,每个进程均运行在其专用且受保护的内存空间内 比如同时打开 Chrome.Xcode,系统就会分别启动2个进 ...

  5. iOS-多线程--(pthread/NSThread/GCD/NSOperation)--总结

    零.线程的注意点(掌握) .不要同时开太多的线程(~3条线程即可,不要超过5条) .线程概念 > 主线程 : UI线程,显示.刷新UI界面,处理UI控件的事件 > 子线程 : 后台线程,异 ...

  6. iOS-多线程--介绍NSThread和GCD及其它们的线程通讯示例

    前言:下面就不一一列出 pthread.NSThread.GCD.NSOperation 的完整的各种方法了,只分别将最常用的列出来,以便偶尔瞄一眼. 一.NSThread 1> 线程间的通讯/ ...

  7. iOS的三种多线程技术NSThread/NSOperation/GCD

    1.iOS的三种多线程技术 1.NSThread 每个NSThread对象对应一个线程,量级较轻(真正的多线程) 2.以下两点是苹果专门开发的"并发"技术,使得程序员可以不再去关心 ...

  8. iOS多线程开发--NSThread NSOperation GCD

    多线程 当用户播放音频.下载资源.进行图像处理时往往希望做这些事情的时候其他操作不会被中 断或者希望这些操作过程中更加顺畅.在单线程中一个线程只能做一件事情,一件事情处理不完另一件事就不能开始,这样势 ...

  9. iOS 多线程 简单学习NSThread NSOperation GCD

    1:首先简单介绍什么叫线程 可并发执行的,拥有最小系统资源,共享进程资源的基本调度单位. 共用堆,自有栈(官方资料说明iOS主线程栈大小为1M,其它线程为512K). 并发执行进度不可控,对非原子操作 ...

随机推荐

  1. SQL Server 2008教程和Microsoft® SQL Server® 2008 R2 SP2 - Express Edition下载

    教程 SQL Server 2008 Tutorialhttp://www.quackit.com/sql_server/sql_server_2008/tutorial/ 数据库下载 Microso ...

  2. Cheatsheet: 2015 06.01 ~ 06.30

    Web The Front-End Optimization Checklist [ASP.NET 5] Production Ready Web Server on Linux. Kestrel + ...

  3. c# 与java之间的简单区别

    C#中类的继承用通过冒号:实现,在Java中用extends C#中实现接口通过冒号:实现,在Java中用implements C#中密封类用sealed实现,在Java中用final C#中常数用c ...

  4. C library function - rewind()

    Description The C library function void rewind(FILE *stream) sets the file position to the beginning ...

  5. <开心一笑> 前端工程师你们伤不起!

    前端工程师你们伤不起!! 来自: 刻铭 2011-03-11 14:09:53 前端工程师伤不起  老子几年前进了互联网圈!!!!!!!成了前端工程师,名字是不是很拉风,有木有!!!!!!!!  尼玛 ...

  6. 程序设计入门——C语言 第4周编程练习 1 素数和(5分)

    题目内容: 我们认为2是第一个素数,3是第二个素数,5是第三个素数,依次类推. 现在,给定两个整数n和m,0<n<=m<=200,你的程序要计算第n个素数到第m个素数之间所有的素数的 ...

  7. RMAN的实战篇--备份脚本

    案列一. 目标: 1.每天夜间1 点执行:2.数据库全备,同时备份控制文件及归档日志文件,备份文件保存至: /backup\目录下,并在完成归档日志文件备份后,自动删除已备份的归档日志:3.备份保留7 ...

  8. IAR更改代码字体&快速模板设置。——Arvin

    1.是用软件提供的字体 如果只想简单的设置,可进行如下设置Tools->IDE Options->Editor->Colors and Fonts->Editor Font-& ...

  9. (37) 在命令行调用API

    l 前言 有时为了更好地调整和改动数据会和到cli ,这会给我们带来更高的效率,基于官网的文档很是简单,这里就带大家一起运用 cli l 搭建 在项目下面有文件odoo.py 这个文件 ,对就是用这个 ...

  10. 解决安装vc2005运行库时提示Command line option syntax error.Type Command/?for Help

    安装vc2005运行库时提示 这是因为它要自解压到用户的临时文件夹下,如果用户名中带中文,就会报错. 简单的解决方法是,手动解压之,再安装 当然,你也可以修改用户名或者再新建个用户.