iOS学习之路--多线程

来源:互联网 发布:波兰式算法 编辑:程序博客网 时间:2024/04/29 22:09
////  TableViewController.m//  UI-W6-L22-Thread////  Created by lanou3g on 15/10/19.//  Copyright (c) 2015年 Seth. All rights reserved.//#import "TableViewController.h"@interface TableViewController ()//线程队列@property (nonatomic,strong)NSOperationQueue *operationQueue;@end@implementation TableViewController- (void)viewDidLoad {    [super viewDidLoad];    // Uncomment the following line to preserve selection between presentations.    // self.clearsSelectionOnViewWillAppear = NO;    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.    // self.navigationItem.rightBarButtonItem = self.editButtonItem;'    //返回主线程的方法    dispatch_sync(dispatch_get_main_queue(), ^{//从子线程回到主线程的方法,但是如果在主线程里面用这个方法,会回不去,卡住程序运行//        NSLog(@"阻塞了");    });    //把耗时的操作放在子线程里执行; 关于UI的添加和刷新都必须在主线程里操作}- (IBAction)leijai:(UIButton *)sender {        int sum = 0;        for (int i = 1; i <= 635500000; i++) {            sum = sum + i;        }    NSLog(@"sum===%d",sum);}-(void)printNumbers {    [[NSThread currentThread] cancel];    for (int i = 0; i < 100 ; i++) {        NSLog(@"%d,当前线程%@",i,[NSThread currentThread] );    }}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}#pragma mark - Table view data source- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {#warning Potentially incomplete method implementation.    // Return the number of sections.    return 1;}- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {#warning Incomplete method implementation.    // Return the number of rows in the section.    return 20;}- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell" forIndexPath:indexPath];    // Configure the cell...    /**     *多线程 1,NSThread     */    //NSThread 创建初始化initwithTarget:执行者selector:选择器 object:参数对象    //通过init方法创建NSThread对象,需要手动开启start    //2 NSThread开启线程并自动执行  //  [NSThread detachNewThreadSelector:@selector(printNumbers) toTarget:self withObject:nil];  //  [self printNumbers];    /**     *NSOPerationQueue 线程队列     */    //1,NSInvocationOperation操作   // NSInvocationOperation *iOP = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumbers) object:nil];    //Operation 是不能自己执行,需要通过队列进行调用 //   [[NSOperationQueue mainQueue] addOperation:iOP];    //2,NSBlockOperation    NSBlockOperation *bOp = [[NSBlockOperation alloc] init];    //以代码块的方式添加操作    [bOp addExecutionBlock:^{        for (int i = 0; i < 100 ; i++) {            NSLog(@"%d,当前线程%@",i,[NSThread currentThread] );        }    }];    //添加到线程队列//    [[NSOperationQueue mainQueue] addOperation:bOp];    [self.operationQueue addOperation:bOp];//    NSLog(@"%@",self.operationQueue.name);    return cell;}//operationQueue的get方法-(NSOperationQueue *)operationQueue {    if (!_operationQueue) {        _operationQueue = [[NSOperationQueue alloc] init];        [_operationQueue setName:@"哈哈"];    }    return _operationQueue;}@end

笔记文件2

////  ViewController.m//  UI-L22-Review-Seth////  Created by lanou3g on 15/10/19.//  Copyright (c) 2015年 Seth. All rights reserved.//#import "ViewController.h"@interface ViewController ()//线程队列@property (nonatomic,strong)NSOperationQueue *opertationQueue;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    // Do any additional setup after loading the view, typically from a nib.    //一个进程是由一个或多个线程组成,进程只负责资源的调度和分配,线程才是程序真正的执行单元,负责代码的执行.    //每个正在运行的程序,至少包含一个线程,这个线程叫做主线程.    //主线程在程序启动时被创建,用于执行main函数    //只有一个主线程的程序,称作单线程程序    //主线程负责执行程序的所有代码,(ui展现及刷新,网络请求,)这些程序只能顺序执行,无法并发执行.    //ios允许用户自己开辟新的线程,相对于主线程来说,这些线程,称作子线程.    //子线程与主线程是独立的运行单元,互不影响,能够并发执行    //ios中关于UI的刷新和添加必须在主线程中操作!!    /**     *NSThread  是一个轻量级的多线程,     */    //1, NSThread开启线程并自动执行    [NSThread detachNewThreadSelector:@selector(printNumbers:) toTarget:self withObject:@"1111"];    [NSThread detachNewThreadSelector:@selector(printNumbers:) toTarget:self withObject:@"2222"];    //2,NSThread 创建初始化initWithTarget:执行者 selector:选择器 object:参数对象    //通过init方法创建NSThread对象,需要手动开启start   NSThread *thread =  [[NSThread alloc] initWithTarget:self selector:@selector(printNumbers:) object:@"333"];    [thread start];    //两种方式区别:第一种方式会立即调用并执行线程,第二种必须调用start方法后才会开始执行线程,在此之前可以对线程进行一些设置,比如线程优先级等;    //使用类方法创建的线程不需要进行内存清理,使用initwithTarget方法创建的线程需要释放内存   // [self printNumbers]; //走主线程 main    /**     * NSOPerationQueue 线程队列     */   //1, NSInvocationOperation 操作    NSInvocationOperation *iOP = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumbers:) object:@"线程队列iOP1"];    //operation不能自己执行 ,需要通过队列进行调用    [[NSOperationQueue mainQueue] addOperation:iOP];//2,    NSBlockOperation    NSBlockOperation *bbbOp = [[NSBlockOperation alloc] init];    //以代码块方式添加操作    [bbbOp addExecutionBlock:^{        for (int i = 0; i < 11; i++) {            NSLog(@"%d,%@",i,[NSThread currentThread]);        }    }];    //添加到线程队列  //  [[NSOperationQueue mainQueue] addOperation:bbbOp];    [self.opertationQueue addOperation:bbbOp];}-(void)printNumbers:(NSString *)string {    [[NSThread currentThread]cancel];    for (int i = 0; i < 15; i++) {        NSLog(@"%d,当前线程%@",i,[NSThread currentThread]);        NSLog(@"我是第%@子线程",string);    }}//operationQueue的get方法-(NSOperationQueue *)opertationQueue {    if (!_opertationQueue) {        _opertationQueue = [[NSOperationQueue alloc] init];        [_opertationQueue setName:@"啊啊啊啊啊"];    }    return _opertationQueue;}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}@end

笔记文件3–共产党 GCD

////  ViewController.m//  UI-W6-L22-GCD////  Created by lanou3g on 15/10/19.//  Copyright (c) 2015年 Seth. All rights reserved.//#import "ViewController.h"@interface ViewController ()- (IBAction)dicclickMaxConButton:(UIButton *)sender;- (IBAction)didClickDependButton:(UIButton *)sender;//线程队列@property (nonatomic,strong)NSOperationQueue *operationQueue;//10.20@property (weak, nonatomic) IBOutlet UIImageView *imageView;- (IBAction)didNsobjectLoadImageButton:(id)sender;//总票数@property (nonatomic,assign)NSInteger count;@end@implementation ViewController- (void)viewDidLoad {    [super viewDidLoad];    self.count = 100;    // Do any additional setup after loading the view, typically from a nib.    //主队列 主线程    NSLog(@"主队列 :%@",[NSOperationQueue mainQueue]);    NSLog(@"主线程 :%@",[NSThread mainThread]);    //NSBlockOperation 创建方式 ,可以便利构造,直接添加block    NSBlockOperation *bOp = [NSBlockOperation blockOperationWithBlock:^{        for (int i = 0; i < 100; i++) {            NSLog(@"%d, 当前线程:%@",i,[NSThread currentThread]);        }    }];    NSBlockOperation *bOp1 = [NSBlockOperation blockOperationWithBlock:^{        for (int i = 0; i < 100; i++) {            NSLog(@"%d,bOp1当前线程: %@",i,[NSThread currentThread]);        }    }];    NSBlockOperation *bOp2 = [NSBlockOperation blockOperationWithBlock:^{        for (int i = 0; i < 100; i++) {            NSLog(@"%d,******当前线程: %@",i,[NSThread currentThread]);        }    }];    //添加到主队列    [[NSOperationQueue mainQueue] addOperation:bOp];    //自定义队列    self.operationQueue = [[NSOperationQueue alloc] init];    [self.operationQueue addOperation:bOp1];    [self.operationQueue addOperation:bOp2];    self.operationQueue = [[NSOperationQueue alloc] init];    //设置最大并发数    self.operationQueue.maxConcurrentOperationCount = 4;    //NSObject 简单后台方法 nsobject任何子类都可以调用    [self performSelectorInBackground:@selector(printNumber:) withObject:nil];#pragma ----GCD 中央派发机制    /** Grand Central Dispath     * 基于函数,使用分发队列     */    //1,主线程队列 ,  等同[NSOperationQueue mainQueue] ,串行    //2,全局线程队列, 后台队列,并行    //3,自定义线程队列,DISPATCH_QUEUE_SERIAL 串行, DISPATCH_QUEUE_CONCURRENT 并行    //创建一个自定义队列    dispatch_queue_t myQueue = dispatch_queue_create("com.lanou3g.www.myQueue", DISPATCH_QUEUE_PRIORITY_DEFAULT);//字符串为c语言字符串,无@,书写格式倒置域名格式    //队列优先级,串行/并行    //dispatch_async(队列,执行block);    //dispatch_sync(队列,执行block);    dispatch_async(myQueue, ^{        [self printNumber:@"GCD"];        [self printNumber:@"G1"];    });    //添加操作    dispatch_async(myQueue, ^{        [self printNumber:@"G2"];    });    // 并行队列    dispatch_queue_t conQueue = dispatch_queue_create("com.lanou3g.www.comQueue", DISPATCH_QUEUE_CONCURRENT);    dispatch_async(conQueue, ^{        [self printNumber:@"G1"];        [self printNumber:@"G2"];    });    dispatch_async(conQueue, ^{        [self printNumber:@"G3"];    });    dispatch_async(conQueue, ^{        [self printNumber:@"G4"];    });}-(void)printNumber:(NSString *)name {    for (int i = 0; i <10; i++) {      //  sleep(1);        NSLog(@"%d,当前线程%@",i,[NSThread currentThread]);        NSLog(@"%@",name);    }}//GCD//在延迟的时间点- (IBAction)didClickAfterButton:(id)sender {    dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(5 * NSEC_PER_SEC) ),dispatch_get_main_queue(), ^{        NSLog(@"等我5秒");    });}//重复执行- (IBAction)didClickApplyButton:(id)sender {    dispatch_apply(10, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(size_t t) { //参数t要添加上        NSLog(@"我在重复,第%zu次",t);//因为设置的全局队列,是并行的,所以输出的次数并没有次序    });}//当一个分组执行结束,notifiy之中的才会执行- (IBAction)didClickNotfyButton:(id)sender {    //创建分组标签    dispatch_group_t groupA = dispatch_group_create();    //使用分组    //创建队列    dispatch_queue_t muQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);    //将操作添加到队列,添加分组标签    dispatch_group_async(groupA, muQueue, ^{        [self printNumber:@"groupA"];    });    dispatch_group_async(groupA, muQueue, ^{        [self printNumber:@"groupAA"];    });    //notify    dispatch_group_notify(groupA, dispatch_get_global_queue (DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{        NSLog(@"groupA的都执行完成以后,我才能执行");    });}//10.20 barrier线程执行时,其他线程不执行- (IBAction)didClickBarrierButton:(id)sender {    //创建队列    dispatch_queue_t muQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);    //将操作添加到队列,添加分组标签    dispatch_async( muQueue, ^{        [self printNumber:@"opA"];    });    dispatch_async(muQueue, ^{        [self printNumber:@"opB"];    });    //将任务添加到队列中 此任务执行是,其他任务停止执行    dispatch_barrier_async(muQueue, ^{        [self printNumber:@"当我执行时,没人跟我抢"];    });    dispatch_async(muQueue, ^{        [self printNumber:@"opC"];    });}//声明单例 ,实现单例static NSObject *object = nil;- (IBAction)didclickOnceButton:(id)sender {    static dispatch_once_t onceToken;//    NSObject *objc = nil;//    __block NSObject *object = objc;    dispatch_once(&onceToken,^{   //once功能 整个程序运行期间,只走一次        object = [[NSObject alloc] init];    });    NSLog(@"%@",object);}//同步执行 10.20- (IBAction)didClickSyncButton:(id)sender {    //同步线程里的内容不执行完成,下面的代码就不会执行    //如果放在主线程里,会阻塞线程 (主线程 diapatch_get_main_queue)    //GCD的方法比前两种多线程容易出错,但是效率高    dispatch_sync(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{        NSLog(@"阻塞");    });}//将函数任务添加到队列- (IBAction)didclickAsyncFButton:(id)sender {    dispatch_async_f(dispatch_get_main_queue(), nil, fun);}//输出 (上面的参数里需要一个c函数,这是一个c函数void fun(){    int i = 10;    while (i > 0) {        printf("HAHAHHA ");        i--;    }}////使用NSObject加载图片,从子线程里下载,在主线程里更新- (IBAction)didNsobjectLoadImageButton:(id)sender {    //NSObject进入子线程    [self performSelectorInBackground:@selector(loadImageUrl) withObject:nil];}-(void)loadImageUrl {    NSURL *url = [NSURL URLWithString:@"http://img3.douban.com/view/event_poster/median/public/10f53a2ad8b38c5.jpg"];    NSData *data = [[NSData alloc] initWithContentsOfURL:url];    UIImage *image = [[UIImage alloc] initWithData:data];    //返回主线程 更新UI    [self.imageView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:YES];//在子线程里下载图片,到主线程里去更新}//线程互斥- (IBAction)ClickLockButton:(id)sender {    //创建线程锁    NSLock *lock = [[NSLock alloc] init];    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{        for (int i = 0; i < 50; i++) {            //加锁            [lock lock];            NSLog(@"小红买到了第%ld张票",self.count);            self.count--;            //解锁            [lock unlock];        }    });    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{        for (int i = 0; i < 50; i++) {            //加锁            [lock lock];            NSLog(@"888绿买到了第%ld张票",self.count);            self.count--;            //解锁            [lock unlock];        }    });}- (void)didReceiveMemoryWarning {    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}//设置最大并发数- (IBAction)dicclickMaxConButton:(UIButton *)sender {    //线程队列的最大并发数    NSInvocationOperation *iOP1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber) object:nil];      NSInvocationOperation *iOP2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber) object:nil];      NSInvocationOperation *iOP3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber) object:nil];      NSInvocationOperation *iOP4 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber) object:nil];      NSInvocationOperation *iOP5 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber) object:nil];      NSInvocationOperation *iOP6 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber) object:nil];    //添加到线程队列    [self.operationQueue addOperations:@[iOP1,iOP2,iOP3,iOP4,iOP5,iOP6] waitUntilFinished:YES];}//设置依赖关系- (IBAction)didClickDependButton:(UIButton *)sender {    NSInvocationOperation *iOP1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber:) object:@"op1"];    NSInvocationOperation *iOP2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber:) object:@"op2"];    NSInvocationOperation *iOP3 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(printNumber:) object:@"op3"];    //线程之间的依赖关系 必须等到被依赖的上一级线程全部执行完成之后,依赖的线程才能开始执行    [iOP1 addDependency:iOP2];    [iOP2 addDependency:iOP3];    [self.operationQueue addOperations:@[iOP1,iOP2,iOP3] waitUntilFinished:YES];}@end
0 0
原创粉丝点击