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

     
    - (id)initWithFrame:(CGRect)frame
    {
    self = [super initWithFrame:frame];
    if (self) {
    count = 3;
    self.backgroundColor = [UIColorredColor];
    [selfsetTitle:[NSStringstringWithFormat:@"%d",count] forState:UIControlStateNormal];
    [selfaddTarget:self action:@selector(clicked) forControlEvents:UIControlEventTouchUpInside];
    }
    return self;
    }
    实现clicked方法,代码如下所示:
    
     
    - (void)clicked {
    [selfremoveFromSuperview];
    self.tag = 1;
    }
    地鼠出现三秒钟没有被点击则自动消失,所以TRMouse类中需要使用detachNewThreadSelector:toTarget:withObject:方法开一个线程用于计时,每隔一秒调用一次refresh方法,地鼠的标题进行三、二、一倒计时显示,最后从界面消失,代码如下所示:
    
     
    - (id)initWithFrame:(CGRect)frame
    {
    self = [super initWithFrame:frame];
    if (self) {
    count = 3;
    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=0;i<4;i++) {
    [selfperformSelectorOnMainThread:@selector(mouseDisapear) withObject:nilwaitUntilDone:NO];
    [NSThread sleepForTimeInterval:1];
    }
    }
    //实现mouseDisappear方法
    -(void)mouseDisapear {
    self.titleLabel.text =[NSStringstringWithFormat:@"%d",count];
    NSLog(@"count = %d",count);
    if (count==0&&self.tag!=1) {
    [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 = 1;
    [self.delegatechangeScoreWithSuccess:YES];
    }
    //失败自动消失
    -(void)mouseDisapear {
    self.titleLabel.text =[NSStringstringWithFormat:@"%d",count];
    NSLog(@"count = %d",count);
    if (count==0&&self.tag!=1) {
    [selfremoveFromSuperview];
    [self.delegatechangeScoreWithSuccess:NO];
    }
    count--;
    }
    步骤三:搭建界面
    
    首先在ViewController类的viewDidLoad方法中开启一个线程,用于定时调用addMouse方法产生地鼠对象,然后返回主线程将产生的地鼠对象添加到界面,代码如下所示:
    
    - (void)viewDidLoad {
    [superviewDidLoad];
    [NSThreaddetachNewThreadSelector:@selector(addMouse) toTarget:selfwithObject:nil];
    }
    - (void)addMouse {
    for (inti=0;;i++) {
    [NSThread sleepForTimeInterval:1];
    [selfperformSelectorOnMainThread:@selector(addMouseView) withObject:nilwaitUntilDone:NO];
    }
    }
    - (void)addMouseView {
    CGSizescreenSize = [[UIScreenmainScreen]bounds].size;
    TRMouse *mouse = [[TRMousealloc]initWithFrame:CGRectMake(arc4random()%(int)(screenSize.width-30), 50+arc4random()%(int)(screenSize.height-80), 30, 30)];
    [self.viewaddSubview:mouse];
    }
    然后ViewController类遵守TRMouseDelegate协议,在创建TRMouse对象时将delegate指定为ViewController,代码如下所示:
    
     
    - (void)addMouseView {
    CGSizescreenSize = [[UIScreenmainScreen]bounds].size;
    TRMouse *mouse = [[TRMousealloc]initWithFrame:CGRectMake(arc4random()%(int)(screenSize.width-30), 50+arc4random()%(int)(screenSize.height-80), 30, 30)];
    mouse.delegate = self;
    [self.viewaddSubview:mouse];
    }
    最后ViewController实现changeScoreWithSuccess:方法,根据isSucces参数修改successLabel和failLabel的显示内容:
    
     
    -(void)changeScoreWithSuccess:(BOOL)isSuccess {
    switch ((int)isSuccess) {
    case 0:{
    int count = [self.failLabel.textintValue];
    self.failLabel.text = [NSStringstringWithFormat:@"%d",++count];
    }
    break;
    case 1:{
    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=0;;i++) {
    [NSThread sleepForTimeInterval:1];
    [selfperformSelectorOnMainThread:@selector(addMouseView) withObject:nilwaitUntilDone:NO];
    }
    }
    - (void)addMouseView {
    CGSizescreenSize = [[UIScreenmainScreen]bounds].size;
    TRMouse *mouse = [[TRMousealloc]initWithFrame:CGRectMake(arc4random()%(int)(screenSize.width-30), 50+arc4random()%(int)(screenSize.height-80), 30, 30)];
    mouse.delegate = self;
    [self.viewaddSubview:mouse];
    }
    -(void)changeScoreWithSuccess:(BOOL)isSuccess {
    switch ((int)isSuccess) {
    case 0:{
    int count = [self.failLabel.textintValue];
    self.failLabel.text = [NSStringstringWithFormat:@"%d",++count];
    }
    break;
    case 1:{
    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 = 3;
    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 = 1;
    [self.delegatechangeScoreWithSuccess:YES];
    }
    - (void)refresh {
    for(inti=0;i<4;i++) {
    [selfperformSelectorOnMainThread:@selector(mouseDisapear) withObject:nilwaitUntilDone:NO];
    [NSThread sleepForTimeInterval:1];
    }
    }
    -(void)mouseDisapear {
    self.titleLabel.text =[NSStringstringWithFormat:@"%d",count];
    NSLog(@"count = %d",count);
    if (count==0&&self.tag!=1) {
    [selfremoveFromSuperview];
    [self.delegatechangeScoreWithSuccess:NO];
    }
    count--;
    }
    @end
  • 相关阅读:
    watir-webdriver使用过程中异常
    分治算法
    回溯算法
    线性时间求取第 K 大数
    深度和广度优先搜索算法
    排序优化——模拟栈及三路快排
    排序算法之——归并排序和快速排序
    数据结构和算法之——算法复杂度分析
    LeetCode 10——正则表达式匹配
    线性代数之——复数矩阵
  • 原文地址:https://www.cnblogs.com/52190112cn/p/5049543.html
Copyright © 2011-2022 走看看