iOS学习笔记——多线程(简单售票系统)

进程是系统资源管理的最小单位。线程是程序执行的最小单位。多线程是一个进程里包含多个线程。一个进程数据会加载到一个内存区间中,其中的线程共享相同的内存空间。各个进程的地址是独立的,只有进程能刷新UI、更新数据。线程需要手动开启。

建立一个简单售票系统,连接线程的运行。首先创建一个单视图工程,在.h文件中代码:

@interface LinViewController : UIViewController
{
    //声明剩余票数、卖出票数成员名
    int _leftTickets;
    int _soldTickets;
    //声明线程成员名
    NSThread * _firstThread;
    NSThread * _secondThread;
    NSThread * _thridThread;
    //声明线程锁
    NSCondition * _ticketsCondition;
}
//创建标签栏的对象,用来显示剩余票数、卖出票数、当前线程名
@property (retain, nonatomic) UILabel * leftLabel;
@property (retain, nonatomic) UILabel * soldLabel;
@property (retain, nonatomic) UILabel * currentThreadLabel;

@end
在.m文件中的代码:
#import "LinViewController.h"

//预编译变量,设置票的总数量
#define MaxTickets 100

@implementation LinViewController

//释放创建的对象
- (void)dealloc
{
    [_leftLabel release];
    [_soldLabel release];
    [_currentThreadLabel release];
    [super dealloc];
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    //加载辅助的标签栏,只显示内容
    [self addLabel:nil];
    
    //设置标签栏对象的位置
    self.leftLabel = [[UILabel alloc]initWithFrame:CGRectMake(150, 90, 100, 30)];
    self.soldLabel = [[UILabel alloc]initWithFrame:CGRectMake(150, 170, 100, 30)];
    self.currentThreadLabel = [[UILabel alloc]initWithFrame:CGRectMake(150, 250, 100, 30)];
    //设置标签栏对象的背景颜色
    self.leftLabel.backgroundColor = [UIColor lightGrayColor];
    self.soldLabel.backgroundColor = [UIColor lightGrayColor];
    self.currentThreadLabel.backgroundColor = [UIColor lightGrayColor];
    //把标签栏添加到当前的视图中
    [self.view addSubview:self.leftLabel];
    [self.view addSubview:self.soldLabel];
    [self.view addSubview:self.currentThreadLabel];
    
    //初始化成员并赋值
    _leftTickets = MaxTickets;
    _soldTickets = 0;
    _ticketsCondition = [[NSCondition alloc]init];
    
    //创建按钮对象
    UIButton * pButton = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    //设置按钮的位置
    [pButton setFrame:CGRectMake(80, 340, 180, 40)];
    //为按钮添加标题
    [pButton setTitle:@"开始卖票" forState:UIControlStateNormal];
    //设置按钮的方法,响应方式
    [pButton addTarget:self action:@selector(threadStart:) forControlEvents:UIControlEventTouchUpInside];
    //把按钮添加到当前视图中
    [self.view addSubview:pButton];
}
#pragma mark-------增加辅助标签栏
- (void)addLabel:(id)sender
{
    //初始化标签栏对象对设置位置
    UILabel * pLabel = [[UILabel alloc]initWithFrame:CGRectMake(10, 20, 300, 40)];
    UILabel * pLabel1 = [[UILabel alloc]initWithFrame:CGRectMake(10, 80, 120, 50)];
    UILabel * pLabel2 = [[UILabel alloc]initWithFrame:CGRectMake(10, 160, 120, 50)];
    UILabel * pLabel3 = [[UILabel alloc]initWithFrame:CGRectMake(10, 240, 120, 50)];
    //设置标签栏的内容文本
    pLabel.text = @"模拟火车票销售---多线程";
    pLabel1.text = @"剩余票数";
    pLabel2.text = @"售出票数";
    pLabel3.text = @"当前进程";
    //设置标签栏的背景颜色
    pLabel.backgroundColor = [UIColor clearColor];
    pLabel1.backgroundColor = [UIColor clearColor];
    pLabel2.backgroundColor = [UIColor clearColor];
    pLabel3.backgroundColor = [UIColor clearColor];
    //设置标签栏的文本居中
    pLabel.textAlignment = NSTextAlignmentCenter;
    pLabel1.textAlignment = NSTextAlignmentCenter;
    pLabel2.textAlignment = NSTextAlignmentCenter;
    pLabel3.textAlignment = NSTextAlignmentCenter;
    //把标签栏对象添加到视图中
    [self.view addSubview:pLabel];
    [self.view addSubview:pLabel1];
    [self.view addSubview:pLabel2];
    [self.view addSubview:pLabel3];
    //释放创建的对象
    [pLabel release];
    [pLabel1 release];
    [pLabel2 release];
    [pLabel3 release];
}
#pragma mark-------开始卖票,线程开始运行
- (void)threadStart:(id)sender
{
    //初始化子线程,设置子线程的方法
    _firstThread = [[NSThread alloc]initWithTarget:self selector:@selector(sellTickets:) object:nil];
    //设置子线程的名字
    [_firstThread setName:@"thread-1"];
    //⭐️手动开启子线程,必须添加,系统不能自主进行
    [_firstThread start];
    
    _secondThread = [[NSThread alloc]initWithTarget:self selector:@selector(sellTickets:) object:nil];
    [_secondThread setName:@"thread-2"];
    [_secondThread start];
    
    _thridThread = [[NSThread alloc]initWithTarget:self selector:@selector(sellTickets:) object:nil];
    [_thridThread setName:@"thread-3"];
    [_thridThread start];
}
//卖票的方法
- (void)sellTickets:(id)sender
{
    while (YES)
    {
        //⭐️锁定线程,防止同一子线程多次运行,必须有
        [_ticketsCondition lock];
        //判断票是否卖完
        if (_leftTickets > 0)
        {
            //设置线程停止0.1秒
            [NSThread sleepForTimeInterval:0.1];
            //卖票的算法
            _leftTickets--;
            _soldTickets = MaxTickets - _leftTickets;
        }
        else if (_leftTickets == 0)
        {
            NSLog(@"票已经卖完!");
            break;
        }
        //子线程调用主线程更新视图,只有进程能更新视图
        [self performSelectorOnMainThread:@selector(updateMyView:) withObject:[[NSThread currentThread]name] waitUntilDone:YES];
        //输出剩余票数、售出票数、当前线程,可以省略
        NSLog(@"剩余票数:%i售出票数:%i当前线程%@",_leftTickets,_soldTickets,[[NSThread currentThread]name]);
        //线程解锁
        [_ticketsCondition unlock];
    }
}
#pragma mark-------更新界面,进程可以,线程不可以
- (void)updateMyView:(id)sender
{
    //设置标签栏的显示内容
    self.leftLabel.text = [NSString stringWithFormat:@"%i",_leftTickets];
    self.soldLabel.text = [NSString stringWithFormat:@"%i",_soldTickets];
    self.currentThreadLabel.text = (NSString *)sender;
    //判断是否卖完,若卖完则弹出警告框
    if (_leftTickets == 0)
    {
        UIAlertView * pAlertView = [[UIAlertView alloc]initWithTitle:@"温馨提示" message:@"票已经全部售出!" delegate:nil cancelButtonTitle:@"确定" otherButtonTitles:nil, nil];
        [pAlertView show];
        [pAlertView release];
    }    
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
}

@end




评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值