• ios学习:多线程一(简单使用)


    xib界面 就放6个UIButton,并将他们的Touch Up Inside 事件与 .h文件里的IBAction关联起来;另外还有两个UILabel,把他们的Outlet与 .h文件里的输出口关联起来就行了.

     1 #import <UIKit/UIKit.h>
     2 #import "TWFXAppDelegate.h"
     3 
     4 @interface TWFXViewController : UIViewController
     5 {
     6     NSOperationQueue *operationQueue;
     7 }
     8 
     9 @property (retain, nonatomic) IBOutlet UILabel *outletData;
    10 
    11 @property (retain, nonatomic) IBOutlet UILabel *outletLabel;
    12 - (IBAction)thread_NSObject:(UIButton *)sender;
    13 - (IBAction)thread_Operation:(UIButton *)sender;
    14 - (IBAction)thread_detch:(UIButton *)sender;
    15 - (IBAction)thread_alloc:(UIButton *)sender;
    16 - (IBAction)thread_OperationBlocks:(UIButton *)sender;
    17 - (IBAction)thread_GCD:(UIButton *)sender;
    18 @end
      1 //
      2 //  TWFXViewController.m
      3 //  DemoMultiThread
      4 //
      5 //  Created by Lion User on 12-12-6.
      6 //  Copyright (c) 2012年 Lion User. All rights reserved.
      7 //
      8 
      9 #import "TWFXViewController.h"
     10 
     11 @interface TWFXViewController ()
     12 
     13 @end
     14 
     15 @implementation TWFXViewController
     16 @synthesize outletLabel = _outletLabel;
     17 - (void)viewDidLoad
     18 {
     19     [super viewDidLoad];
     20     // Do any additional setup after loading the view, typically from a nib.
     21     
     22     //创建线程队列(线程池)
     23     operationQueue = [[NSOperationQueue alloc] init];
     24     
     25     /*
     26      设置线程池中的线程数,也就是并发操作数,默认是-1,也就是不限数量,同时运行队列中的所有操作
     27      */
     28     [operationQueue setMaxConcurrentOperationCount:2];
     29     
     30     
     31     
     32     self.outletLabel.textAlignment = NSTextAlignmentCenter;
     33     self.outletLabel.text = @"test";
     34 }
     35 
     36 - (void)didReceiveMemoryWarning
     37 {
     38     [super didReceiveMemoryWarning];
     39     // Dispose of any resources that can be recreated.
     40     self.outletLabel = nil;
     41 }
     42 
     43 - (void)dealloc {
     44     [_outletLabel release];
     45     [operationQueue release];
     46     [_outletData release];
     47     [super dealloc];
     48 }
     49 
     50 
     51 
     52 /*
     53  不显示创建线程的方法
     54  创建后台线程,方法1
     55  这种方式,在方法被调用时,会立马创建一个后台线程并运行
     56  */
     57 - (IBAction)thread_NSObject:(UIButton *)sender {
     58     
     59     [self performSelectorInBackground:@selector(doSomething:) withObject:@"performSelectorInBackground"];
     60 }
     61 
     62 
     63 
     64 /*
     65  NSThread 类----类方法
     66  创建后台线程,方法3
     67  这种方式,在方法被调用时,会立马创建一个后台线程并运行
     68  和方法1一样
     69  
     70  NSThread 类 量级比较轻,但需要自己管理线程的生命周期 和 线程同步 等
     71  线程的同步对数据的加锁需要一定的开销
     72  */
     73 - (IBAction)thread_detch:(UIButton *)sender {
     74     
     75     [NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:@"detachNewThreadSelector"];
     76 }
     77 
     78 
     79 /*
     80  NSThread类----实例方法
     81  创建后台线程,方法4
     82  这种方式,虽然alloc init 了,但需要手动调用 start 方法来启动线程,在启动之前,可以对线程进行一些设置,比如stack大小 优先级等
     83  */
     84 - (IBAction)thread_alloc:(UIButton *)sender {
     85     
     86     NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(doSomething:) object:@"NSThread alloc inittWithTarget"];
     87     
     88     [thread setName:@"thread_alloc"]; //设置线程名字
     89     [thread setStackSize:100];//设置stack大小
     90     [thread setThreadPriority:10.f]; //设置线程优先级
     91     
     92     [thread start];//启动线程
     93 }
     94 
     95 
     96 
     97 
     98 
     99 
    100 /*
    101  NSOperation类 --- NSInvocastionOperation
    102  不需要关心 线程管理 数据同步 等问题,把焦点放在需要实现的地方
    103  创建后台线程,方法2
    104  NSOperation 是抽象类,需要自定义其子类,或者使用他的两个一经实现了的子列:NSInvocationOperation  NSBlockOperation
    105  然后把线程添加到线程队列里
    106  
    107  */
    108 - (IBAction)thread_Operation:(UIButton *)sender {
    109     
    110     NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(doSomething:) object:@"NSInvocationOperation"];
    111     
    112     [operationQueue addOperation:op];//把线程加到线程队列里,然后线程立马启动
    113 }
    114 
    115 
    116 
    117 /*
    118  NSOperation类 --- NSBlockOperation
    119  可以添加多个block,执行顺序呢?
    120  */
    121 - (IBAction)thread_OperationBlocks:(UIButton *)sender {
    122     
    123     NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^(void){
    124         
    125         for (int i = 0; i < 1000; i++) {
    126             
    127             NSString *text = [[[NSString alloc] initWithFormat:@"%d", i] autorelease];
    128             
    129             
    130             /*
    131              在这里不能通过 self XXXX 来操作界面,要通过调用主线程的方法来实现,把要对UI的操作放在主线程的方法里
    132              */
    133             //  self.outletLabel.text = text;
    134             [self performSelectorOnMainThread:@selector(updateUI:) withObject:text waitUntilDone:YES];
    135             
    136         }
    137     }];
    138     
    139     
    140     [op addExecutionBlock:^(void){
    141         
    142         for (int i = 0; i < 1000; i++) {
    143             
    144             NSString *text = [[[NSString alloc] initWithFormat:@"%d", i] autorelease];
    145             
    146             
    147             /*
    148              在这里不能通过 self XXXX 来操作界面,要通过调用主线程的方法来实现,把要对UI的操作放在主线程的方法里
    149              */
    150             //  self.outletLabel.text = text;
    151             [self performSelectorOnMainThread:@selector(updateLabel:) withObject:text waitUntilDone:YES];
    152             
    153         }
    154     }];
    155     
    156     
    157     [operationQueue addOperation:op];
    158 
    159 }
    160 
    161 
    162 
    163 
    164 /*
    165  GCD: 以优化的应用程序支持多核心处理器和其他的对称多处理系统的系统
    166  工作原理:让程序平行排队的特定任务根据可用的处理资源,安排他们在任何可用的处理器核心上执行任务,一个任务可以是一个函数(function) 或者是一个block
    167  GCD中的队列采用FIFO(先进先出)机制,保证先进来的任务得以优先执行.(优先开始不代表早点结束)
    168  GCD里的队列(线程池?)分下面三种:
    169  Serial:private  dispatch queues,同时只执行一个任务,通常用于同步访问特定的资源或数据
    170  Concurrent: global dispatch queue;可以并发执行多个任务,执行完成的顺序是随机的.
    171              系统给每个应用程序提供三个concurrent dispatch queues,这三个并发调度队列是全局的,只有优先级的不同
    172  Main dispatch queue: 全局可用的serial queue,是在应用程序主线程上执行任务的.就是UI线程?
    173  */
    174 - (IBAction)thread_GCD:(UIButton *)sender {
    175     
    176     
    177     //dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0):获取一个并发的全局队列,把block加到队列里
    178     
    179     dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) {
    180        
    181         //获取主线程队列,把一个block加到队列里
    182         dispatch_async(dispatch_get_main_queue(), ^(void) {
    183                             
    184           self.outletData.text = @"gcd!";
    185             
    186         } );
    187         
    188         for (int i = 0; i < 1000; i++) {
    189             
    190             NSString *text = [[[NSString alloc] initWithFormat:@"%d", i]autorelease];
    191             
    192             dispatch_async(dispatch_get_main_queue(), ^(void){
    193                 
    194                 self.outletLabel.text = text;
    195             });
    196         }
    197     });
    198     
    199     dispatch_async(dispatch_get_main_queue(), ^(void){
    200         
    201         self.outletData.text = @"gcd had changed";
    202     });
    203     
    204 }
    205 
    206 
    207 /*
    208  该方法被后台线程调用,在这里不能操作主线程的东西,例如UI线程
    209  要想操作UI,得调用主线程的方法来操作
    210  作为多线程的回调方法,需要自行管理内存的释放,否则会引起泄露    
    211  */
    212 -(void)doSomething:(id)data
    213 {
    214     @autoreleasepool {
    215         
    216         [self performSelectorOnMainThread:@selector(updateLabel:) withObject:data waitUntilDone:YES];
    217         for (int i = 0; i < 1000; i++) {
    218             
    219             NSString *text = [[[NSString alloc] initWithFormat:@"%d", i] autorelease];
    220             
    221             
    222             /*
    223              线程间通信:通知主线程
    224              在这里不能通过 self XXXX 来操作界面,要通过调用主线程的方法来实现,把要对UI的操作放在主线程的方法里
    225              */
    226           //  self.outletLabel.text = text;
    227             [self performSelectorOnMainThread:@selector(updateUI:) withObject:text waitUntilDone:YES];
    228 
    229         }
    230         
    231         data = @"value had changed!";
    232         [self performSelectorOnMainThread:@selector(updateLabel:) withObject:data waitUntilDone:YES];
    233 
    234     }
    235  
    236 }
    237 
    238 
    239 /*
    240  刷新界面,作为回调函数被调用
    241  */
    242 -(void)updateUI:(NSString *) text
    243 {
    244   //  self.outletLabel.textAlignment = NSTextAlignmentCenter;
    245     self.outletLabel.text = text;
    246 }
    247 
    248 
    249 -(void)updateLabel:(NSString *) data
    250 {
    251     self.outletData.text = data;
    252 }
    253 
    254 
    255 @end
  • 相关阅读:
    SQL优化之博客案例
    Drools之规则属性
    Android 8.0以上系统应用如何保活
    Android 8.0(api27)静态广播和动态广播接收问题
    Android开发 WorkManager详解
    使用EOS Camera Movie Record 软件在计算机上使用 Canon EOS DSLR相机录制视频 。
    关于使用AlarmManager的注意事项
    系统服务之定时服务(AlarmManager)
    Android定时器AlarmManager
    Android 代码混淆
  • 原文地址:https://www.cnblogs.com/zouzf/p/2805336.html
Copyright © 2020-2023  润新知