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

 

posted @ 2012-12-11 14:56  仙外仙  阅读(955)  评论(0编辑  收藏  举报