##iOS开发之多线程开发之NSThread

2016-03-08  本文已影响61人  纳萨立克

在每个iOS应用程序中,都存在一个线程用来显示界面,更新UI,处理触摸时间的主线程(Main),当我们的需求中需要有一个特别消耗时间的操作的时候,如果我们把这样的操作放在主线程中完成的话,就会造成主线程堵塞,界面卡死,这样极大的影响了用户体验.一般这种需求我们可以通过多线程在实现,把这样的耗时的操作放到另外的一个线程中去执行,提高了用户体验和运行效率.

在iOS中的多线程主要有pthread,NSThread,GCD, NSOperation.

技术方案 语言 线程生命周期 使用频率
pthred C 程序员管理 几乎不用
NSThread OC 程序员管理 偶尔使用
GCD C 自动管理 经常使用
NSOperation OC 自动管理 经常使用

一.Ptheard (基本不使用)

  • 一套通用的多线程API
#import "ViewController.h"
#import <pthread.h>
@interface ViewController ()

@end

@implementation ViewController


void * run(void *param)
{
    for (NSInteger i = 0; i<50000; i++) {
        NSLog(@"-----%zd--%@", i, [NSThread currentThread]);
    }
    return NULL;
}


- (void)viewDidLoad {
    [super viewDidLoad];

    pthread_t thread;
    
    pthread_create(&thread, NULL, run, NULL);
    
}


二. NSThread (偶尔使用)

  • 使用更加面向对象

1. NSThread的初始化

2. 线程间通讯

[self performSelector:@selector(run) onThread:thread withObject:nil waitUntilDone:YES];
[self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:YES];  

[self performSelector:@selector(run) withObject:nil];  

3. 线程安全

在多线程中,多个线程同时对同一个资源进行操作的时候,就会出现线程安全的问题,解决这问题的方法是:我们给这个资源加锁.即当一个线程开始操作改资源的时候,会给改资源加上一把锁,这样其他的线程是不可以对该资源进行读写等操作,当线程对该资源的操作完成是,就会把锁打开,让其他的线程对该资源进行操作.加锁对于资源是比较消耗性能的.

#import "ViewController.h"

@interface ViewController ()
/** 售票员01 */
@property (nonatomic, strong) NSThread *thread01;
/** 售票员02 */
@property (nonatomic, strong) NSThread *thread02;
/** 售票员03 */
@property (nonatomic, strong) NSThread *thread03;

/** 票的总数 */
@property (nonatomic, assign) NSInteger ticketCount;


@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    
    self.ticketCount = 100;
    
    self.thread01 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
    self.thread01.name = @"售票员01";
    
    self.thread02 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
    self.thread02.name = @"售票员02";
    
    self.thread03 = [[NSThread alloc] initWithTarget:self selector:@selector(saleTicket) object:nil];
    self.thread03.name = @"售票员03";
}

- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
    [self.thread01 start];
    [self.thread02 start];
    [self.thread03 start];
}

- (void)saleTicket
{
    while (1) {
        //加锁,对该资源的锁必须为同一把锁
        @synchronized(self) {
            // 先取出总数
            NSInteger count = self.ticketCount;
            if (count > 0) {
                self.ticketCount = count - 1;
                NSLog(@"%@卖了一张票,还剩下%zd张", [NSThread currentThread].name, self.ticketCount);
            } else {
                NSLog(@"票已经卖完了");
                break;
            }
        }
    }
}


上一篇下一篇

猜你喜欢

热点阅读