zoukankan      html  css  js  c++  java
  • 线程和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
  • 相关阅读:
    Java--环境变量(jdk、jre)配置
    Jsoup爬取数据设置代理IP
    数据库连接的莫名问题:create connection error
    springBoot使用过程的小感悟
    Activiti工作流引擎数据库表结构
    IDEA创建Activiti工作流开发
    Java开源爬虫框架WebCollector设置代理
    使用OkHttpClient爬取json数据
    雪中的杭州
    StringBuffer中的append方法
  • 原文地址:https://www.cnblogs.com/hytx/p/5051927.html
Copyright © 2011-2022 走看看