您的位置:首页 > 移动开发 > IOS开发

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

2014-01-02 08:47 441 查看
进程是系统资源管理的最小单位。线程是程序执行的最小单位。多线程是一个进程里包含多个线程。一个进程数据会加载到一个内存区间中,其中的线程共享相同的内存空间。各个进程的地址是独立的,只有进程能刷新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
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: