线程和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,并添加点击事件当地鼠出现在界面三秒钟之内被点击即消失,代码如下所示:

 
  1. (id)initWithFrame:(CGRect)frame
  2. {
  3. self [super initWithFrame:frame];
  4. if (self{
  5. count 3;
  6. self.backgroundColor [UIColorredColor];
  7. [selfsetTitle:[NSStringstringWithFormat:@"%d",count] forState:UIControlStateNormal];
  8. [selfaddTarget:self action:@selector(clicked) forControlEvents:UIControlEventTouchUpInside];
  9. }
  10. return self;
  11. }

实现clicked方法,代码如下所示:

 
  1. (void)clicked {
  2. [selfremoveFromSuperview];
  3. self.tag 1;
  4. }

地鼠出现三秒钟没有被点击则自动消失,所以TRMouse类中需要使用detachNewThreadSelector:toTarget:withObject:方法开一个线程用于计时,每隔一秒调用一次refresh方法,地鼠的标题进行三、二、一倒计时显示,最后从界面消失,代码如下所示:

 
  1. (id)initWithFrame:(CGRect)frame
  2. {
  3. self [super initWithFrame:frame];
  4. if (self{
  5. count 3;
  6. self.backgroundColor [UIColorredColor];
  7. [selfsetTitle:[NSStringstringWithFormat:@"%d",count] forState:UIControlStateNormal];
  8. [selfaddTarget:self action:@selector(clicked) forControlEvents:UIControlEventTouchUpInside];
  9. }
  10. [NSThreaddetachNewThreadSelector:@selector(refresh) toTarget:selfwithObject:nil];
  11. return self;
  12. }
  13. //实现refresh方法
  14. (void)refresh {
  15. for(inti=0;i<4;i++) {
  16. [selfperformSelectorOnMainThread:@selector(mouseDisapear) withObject:nilwaitUntilDone:NO];
  17. [NSThread sleepForTimeInterval:1];
  18. }
  19. }
  20. //实现mouseDisappear方法
  21. -(void)mouseDisapear {
  22. self.titleLabel.text =[NSStringstringWithFormat:@"%d",count];
  23. NSLog(@"count = %d",count);
  24. if (count==0&&self.tag!=1{
  25. [selfremoveFromSuperview];
  26. }
  27. count--;
  28. }

步骤二:添加成功标签和失败标签

首先在Storyboard的场景中拖放两个Label分别用于显示成功的计数和失败的计数,并关联成ViewController的输出口属性successLabel和failLabel,代码如下所示:

  1. @interfaceViewController ()
  2. @property (weak, nonatomicIBOutletUILabel *successLabel;
  3. @property (weak, nonatomicIBOutletUILabel *failLabel;
  4. @end

当成功点击地鼠时成功计数加一,地鼠自动消失失败计数加一,该功能可以通过委托协议来实现,在TRMouse类中定义一个TRMouseDelegate协议,该协议有一个需要实现的方法-(void)changeScoreWithSuccess:(BOOL)isSuccess,代码如下所示:

  1. @protocolTRMouseDelegate
  2. -(void)changeScoreWithSuccess:(BOOL)isSuccess;
  3. @end

再在TRMouse类中定义一个公开的属性id<TRMouseDelegate>delegate,用于指定委托对象,代码如下所示:

 
  1. @interfaceTRMouse : UIButton
  2. @property (nonatomic,assignid<TRMouseDelegate> delegate;
  3. @end

最后在成功点击地鼠消失方法中delegate调用changeScoreWithSuccess:方法isSuccess参数传入YES,在地鼠自动消失的方法delegate调用changeScoreWithSuccess:方法isSuccess参数传入NO,代码如下所示:

  1. //成功点击
  2. (void)clicked {
  3. [selfremoveFromSuperview];
  4. self.tag 1;
  5. [self.delegatechangeScoreWithSuccess:YES];
  6. }
  7. //失败自动消失
  8. -(void)mouseDisapear {
  9. self.titleLabel.text =[NSStringstringWithFormat:@"%d",count];
  10. NSLog(@"count = %d",count);
  11. if (count==0&&self.tag!=1{
  12. [selfremoveFromSuperview];
  13. [self.delegatechangeScoreWithSuccess:NO];
  14. }
  15. count--;
  16. }

步骤三:搭建界面

首先在ViewController类的viewDidLoad方法中开启一个线程,用于定时调用addMouse方法产生地鼠对象,然后返回主线程将产生的地鼠对象添加到界面,代码如下所示:

  1. (void)viewDidLoad {
  2. [superviewDidLoad];
  3. [NSThreaddetachNewThreadSelector:@selector(addMouse) toTarget:selfwithObject:nil];
  4. }
  5. (void)addMouse {
  6. for (inti=0;;i++) {
  7. [NSThread sleepForTimeInterval:1];
  8. [selfperformSelectorOnMainThread:@selector(addMouseView) withObject:nilwaitUntilDone:NO];
  9. }
  10. }
  11. (void)addMouseView {
  12. CGSizescreenSize [[UIScreenmainScreen]bounds].size;
  13. TRMouse *mouse [[TRMousealloc]initWithFrame:CGRectMake(arc4random()%(int)(screenSize.width-30), 50+arc4random()%(int)(screenSize.height-80), 3030)];
  14. [self.viewaddSubview:mouse];
  15. }

然后ViewController类遵守TRMouseDelegate协议,在创建TRMouse对象时将delegate指定为ViewController,代码如下所示:

 
  1. (void)addMouseView {
  2. CGSizescreenSize [[UIScreenmainScreen]bounds].size;
  3. TRMouse *mouse [[TRMousealloc]initWithFrame:CGRectMake(arc4random()%(int)(screenSize.width-30), 50+arc4random()%(int)(screenSize.height-80), 3030)];
  4. mouse.delegate = self;
  5. [self.viewaddSubview:mouse];
  6. }

最后ViewController实现changeScoreWithSuccess:方法,根据isSucces参数修改successLabel和failLabel的显示内容:

 
  1. -(void)changeScoreWithSuccess:(BOOL)isSuccess {
  2. switch ((int)isSuccess{
  3. case 0:{
  4. int count [self.failLabel.textintValue];
  5. self.failLabel.text [NSStringstringWithFormat:@"%d",++count];
  6. }
  7. break;
  8. case 1:{
  9. int count [self.successLabel.textintValue];
  10. self.successLabel.text [NSStringstringWithFormat:@"%d",++count];
  11. }
  12. }
  13. }

1.4 完整代码

本案例中,ViewController.m文件中的完整代码如下所示:

 
  1. #import "ViewController.h"
  2. @interfaceViewController () <TRMouseDelegate>
  3. @property (weak, nonatomicIBOutletUILabel *successLabel;
  4. @property (weak, nonatomicIBOutletUILabel *failLabel;
  5. @end
  6. @implementationViewController
  7. (void)viewDidLoad {
  8. [superviewDidLoad];
  9. [NSThreaddetachNewThreadSelector:@selector(addMouse) toTarget:selfwithObject:nil];
  10. }
  11. (void)addMouse {
  12. for (inti=0;;i++) {
  13. [NSThread sleepForTimeInterval:1];
  14. [selfperformSelectorOnMainThread:@selector(addMouseView) withObject:nilwaitUntilDone:NO];
  15. }
  16. }
  17. (void)addMouseView {
  18. CGSizescreenSize [[UIScreenmainScreen]bounds].size;
  19. TRMouse *mouse [[TRMousealloc]initWithFrame:CGRectMake(arc4random()%(int)(screenSize.width-30), 50+arc4random()%(int)(screenSize.height-80), 3030)];
  20. mouse.delegate = self;
  21. [self.viewaddSubview:mouse];
  22. }
  23. -(void)changeScoreWithSuccess:(BOOL)isSuccess {
  24. switch ((int)isSuccess{
  25. case 0:{
  26. int count [self.failLabel.textintValue];
  27. self.failLabel.text [NSStringstringWithFormat:@"%d",++count];
  28. }
  29. break;
  30. case 1:{
  31. int count [self.successLabel.textintValue];
  32. self.successLabel.text [NSStringstringWithFormat:@"%d",++count];
  33. }
  34. }
  35. }
  36. @end
 

本案例中,TRMouse.h文件中的完整代码如下所示:

 
  1. #import<UIKit/UIKit.h>
  2. @protocolTRMouseDelegate
  3. -(void)changeScoreWithSuccess:(BOOL)isSuccess;
  4. @end
  5. @interfaceTRMouse : UIButton
  6. @property (nonatomic,assignid<TRMouseDelegate> delegate;
  7. @end
 

本案例中,TRMouse.m文件中的完整代码如下所示:

 
  1. #import "TRMouse.h"
  2. @interfaceTRMouse (){
  3. int count;
  4. }
  5. @end
  6. @implementationTRMouse
  7. (id)initWithFrame:(CGRect)frame
  8. {
  9. self [super initWithFrame:frame];
  10. if (self{
  11. count 3;
  12. self.backgroundColor [UIColorredColor];
  13. [selfsetTitle:[NSStringstringWithFormat:@"%d",count] forState:UIControlStateNormal];
  14. [selfaddTarget:self action:@selector(clicked) forControlEvents:UIControlEventTouchUpInside];
  15. }
  16. [NSThreaddetachNewThreadSelector:@selector(refresh) toTarget:selfwithObject:nil];
  17. return self;
  18. }
  19. (void)clicked {
  20. [selfremoveFromSuperview];
  21. self.tag 1;
  22. [self.delegatechangeScoreWithSuccess:YES];
  23. }
  24. (void)refresh {
  25. for(inti=0;i<4;i++) {
  26. [selfperformSelectorOnMainThread:@selector(mouseDisapear) withObject:nilwaitUntilDone:NO];
  27. [NSThread sleepForTimeInterval:1];
  28. }
  29. }
  30. -(void)mouseDisapear {
  31. self.titleLabel.text =[NSStringstringWithFormat:@"%d",count];
  32. NSLog(@"count = %d",count);
  33. if (count==0&&self.tag!=1{
  34. [selfremoveFromSuperview];
  35. [self.delegatechangeScoreWithSuccess:NO];
  36. }
  37. count--;
  38. }
  39. @end
原文地址:https://www.cnblogs.com/hytx/p/5051927.html