你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS學習筆記——多線程(簡單售票系統)

iOS學習筆記——多線程(簡單售票系統)

編輯: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. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved