IOS多线程开发之NSThread

概要

        使用NSThread的例子,线程创建、启动、线程同步、锁、线程的交互,需要注意的时线程的交互,因为IOS规定只有主线程能够修改UI,所以如果子线程要修改UI的话,需要与主线程交互,即调用方法- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;实现

示例代码

//
//  ViewController.m
//  NSThreadDemo
//
//  Created by wangwei on 14/12/31.
//  Copyright (c) 2014年 arbboter. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
{
    NSMutableArray* sellTicketThread;
    NSCondition* sellTicketCondition;
    NSInteger numberOfSellThread;
    NSInteger nunberOfTickets;
}

@end

@implementation ViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    
    sellTicketThread = [[NSMutableArray alloc] init];
    
    numberOfSellThread = 3;
    nunberOfTickets = 24;
    
    /** create thread */
    NSThread* sellTicket = nil;
    for (NSInteger i=0; i<numberOfSellThread; i++)
    {
        sellTicket = [[NSThread alloc] initWithTarget:self selector:@selector(sellTicket) object:nil];
        sellTicket.name = [NSString stringWithFormat:@"Ticket Windows %ld", i];
        [sellTicketThread addObject:sellTicket];
    }
    
    /** create thread condition */
    sellTicketCondition = [[NSCondition alloc] init];
    
    /** start all thread */
    for (NSThread* t in sellTicketThread)
    {
        [t start];
    }
    
    self.messageTicket.frame = CGRectMake(0, 20, 330, 600);
    self.messageTicket.text = @"Welcome to 12306.\n";
    self.messageTicket.textColor = [UIColor blackColor];
    self.messageTicket.editable = NO;
}

- (void) sellTicket
{
    NSString* message = nil;
    BOOL bRun = YES;
    
    while (bRun)
    {
        [sellTicketCondition lock];
        
        if (nunberOfTickets>0)
        {
            nunberOfTickets--;
            message = [NSString stringWithFormat:@"[%@] get ticket %02ld. [%02ld Left]\n",
                       [[NSThread currentThread] name], nunberOfTickets+1, nunberOfTickets];
        }
        else
        {
            message = [NSString stringWithFormat:@"[%@] Sorry, but we have no ticket lefy.\n", [[NSThread currentThread] name]];
            bRun = NO;
        }
        
        /** 子线程不能修改APP的UI的, 所以需要主线程修改 */
        [self performSelectorOnMainThread:@selector(addMessageToView:) withObject:message waitUntilDone:YES];

        [sellTicketCondition unlock];
        
        /** wait for a moment */
        sleep(arc4random()%5+1);
    }
}

/** 交互信息 */
- (void)addMessageToView:(NSString*)message
{
    self.messageTicket.text = [self.messageTicket.text stringByAppendingString:message];
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

结果展示

技术分享

主要方法列

 //返回当前线程
+ (NSThread *)currentThread;          

// 通过类方法创建一个线程
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;

// 判断是否为多线程
+ (BOOL)isMultiThreaded;


- (NSMutableDictionary *)threadDictionary;

+ (void)sleepUntilDate:(NSDate *)date;

+ (void)sleepForTimeInterval:(NSTimeInterval)ti;

//  退出线程
+ (void)exit;

// 线程属性值
+ (double)threadPriority ;
+ (BOOL)setThreadPriority:(double)p ;

// 线程函数地址
+ (NSArray *)callStackReturnAddresses;

// 设置与返回线程名称
- (void)setName:(NSString *)n;
- (NSString *)name;

// 线程堆栈
- (NSUInteger)stackSize;
- (void)setStackSize:(NSUInteger)s;

// 判断当前线程是否为主线程
- (BOOL)isMainThread;
+ (BOOL)isMainThread;

+ (NSThread *)mainThread;

// 线程对象初始化操作   (通过创建线程对象 ,需要 手工指定线程函数与各种属性)
- (id)init;

// 在线程对象初始化时创建一个线程(指定线程函数)
- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;

// 是否在执行
- (BOOL)isExecuting;

// 是否已经结束 
- (BOOL)isFinished;

// 是否取消的
- (BOOL)isCancelled;

// 取消操作
- (void)cancel;

// 在主线程上执行aSelector所对应的代码,因为有些代码只能在主线程上执行,比如修改UI
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;

// 线程启动
- (void)start;

- (void)main;    // thread body method


郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。