iOS多執行緒程式設計之NSThread的使用
1、簡介:
1.1 iOS有三種多執行緒程式設計的技術,分別是:
1.、NSThread
2、Cocoa NSOperation (iOS多執行緒程式設計之NSOperation和NSOperationQueue的使用)
3、GCD 全稱:Grand Central Dispatch( iOS多執行緒程式設計之Grand Central Dispatch(GCD)介紹和使用)
這三種程式設計方式從上到下,抽象度層次是從低到高的,抽象度越高的使用越簡單,也是Apple最推薦使用的。
這篇我們主要介紹和使用NSThread,後面會繼續2、3 的講解和使用。
1.2 三種方式的有缺點介紹:
NSThread:
優點:NSThread 比其他兩個輕量級
缺點:需要自己管理執行緒的生命週期,執行緒同步。執行緒同步對資料的加鎖會有一定的系統開銷
NSThread實現的技術有下面三種:
Technology |
Description |
---|---|
Cocoa threads |
Cocoa implements threads using the |
POSIX threads |
POSIX threads provide a C-based interface for creating threads. If you are not writing a Cocoa application, this is the best choice for creating threads. The POSIX interface is relatively simple to use and offers ample flexibility for configuring your threads. For more information, see “Using POSIX Threads” |
Multiprocessing Services |
Multiprocessing Services is a legacy C-based interface used by applications transitioning from older versions of Mac OS. This technology is available in OS X only and should be avoided for any new development. Instead, you should use the |
Cocoa operation
優點:不需要關心執行緒管理,資料同步的事情,可以把精力放在自己需要執行的操作上。
Cocoa operation 相關的類是 NSOperation ,NSOperationQueue。NSOperation是個抽象類,使用它必須用它的子類,可以實現它或者使用它定義好的兩個子類:NSInvocationOperation 和 NSBlockOperation。建立NSOperation子類的物件,把物件新增到NSOperationQueue佇列裡執行。
GCD
Grand Central Dispatch (GCD)是Apple開發的一個多核程式設計的解決方法。在iOS4.0開始之後才能使用。GCD是一個替代諸如NSThread, NSOperationQueue, NSInvocationOperation等技術的很高效和強大的技術。現在的iOS系統都升級到6了,所以不用擔心該技術不能使用。
介紹完這三種多執行緒程式設計方式,我們這篇先介紹NSThread的使用。
2、NSThread的使用
2.1 NSThread 有兩種直接建立方式:
- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument
+ (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument
第一個是例項方法,第二個是類方法
- 1、[NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil];
- 2、NSThread* myThread = [[NSThread alloc] initWithTarget:self
- selector:@selector(doSomething:)
- object:nil];
- [myThread start];
2.2引數的意義:
selector :執行緒執行的方法,這個selector只能有一個引數,而且不能有返回值。
target :selector訊息傳送的物件
argument:傳輸給target的唯一引數,也可以是nil
第一種方式會直接建立執行緒並且開始執行執行緒,第二種方式是先建立執行緒物件,然後再執行執行緒操作,在執行執行緒操作前可以設定執行緒的優先順序等執行緒資訊
2.3 PS:不顯式建立執行緒的方法:
用NSObject的類方法 performSelectorInBackground:withObject: 建立一個執行緒:
[Obj performSelectorInBackground:@selector(doSomething) withObject:nil];
2.4 下載圖片的例子:
2.4.1 新建singeView app
新建專案,並在xib檔案上放置一個imageView控制元件。按住control鍵拖到viewControll
er.h檔案中建立imageView IBOutlet
ViewController.m中實現:
- //
- // ViewController.m
- // NSThreadDemo
- //
- // Created by rongfzh on 12-9-23.
- // Copyright (c) 2012年 rongfzh. All rights reserved.
- //
- #import "ViewController.h"
- #define kURL @"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"
- @interface ViewController ()
- @end
- @implementation ViewController
- -(void)downloadImage:(NSString *) url{
- NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
- UIImage *image = [[UIImage alloc]initWithData:data];
- if(image == nil){
- }else{
- [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
- }
- }
- -(void)updateUI:(UIImage*) image{
- self.imageView.image = image;
- }
- - (void)viewDidLoad
- {
- [super viewDidLoad];
- // [NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:self withObject:kURL];
- NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(downloadImage:) object:kURL];
- [thread start];
- }
- - (void)didReceiveMemoryWarning
- {
- [super didReceiveMemoryWarning];
- // Dispose of any resources that can be recreated.
- }
- @end
2.4.2執行緒間通訊
執行緒下載完圖片後怎麼通知主執行緒更新介面呢?
[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
performSelectorOnMainThread是NSObject的方法,除了可以更新主執行緒的資料外,還可以更新其他執行緒的比如:用:performSelector:onThread:withObject:waitUntilDone:
執行下載圖片:
圖片下載下來了。
2.3 執行緒同步
我們演示一個經典的賣票的例子來講NSThread的執行緒同步:
.h
- #import <UIKit/UIKit.h>
- @class ViewController;
- @interface AppDelegate : UIResponder <UIApplicationDelegate>
- {
- int tickets;
- int count;
- NSThread* ticketsThreadone;
- NSThread* ticketsThreadtwo;
- NSCondition* ticketsCondition;
- NSLock *theLock;
- }
- @property (strong, nonatomic) UIWindow *window;
- @property (strong, nonatomic) ViewController *viewController;
- @end
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- {
- tickets = 100;
- count = 0;
- theLock = [[NSLock alloc] init];
- // 鎖物件
- ticketsCondition = [[NSCondition alloc] init];
- ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
- [ticketsThreadone setName:@"Thread-1"];
- [ticketsThreadone start];
- ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
- [ticketsThreadtwo setName:@"Thread-2"];
- [ticketsThreadtwo start];
- self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
- // Override point for customization after application launch.
- self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
- self.window.rootViewController = self.viewController;
- [self.window makeKeyAndVisible];
- return YES;
- }
- - (void)run{
- while (TRUE) {
- // 上鎖
- // [ticketsCondition lock];
- [theLock lock];
- if(tickets >= 0){
- [NSThread sleepForTimeInterval:0.09];
- count = 100 - tickets;
- NSLog(@"當前票數是:%d,售出:%d,執行緒名:%@",tickets,count,[[NSThread currentThread] name]);
- tickets--;
- }else{
- break;
- }
- [theLock unlock];
- // [ticketsCondition unlock];
- }
- }
上面例子我使用了兩種鎖,一種NSCondition ,一種是:NSLock。 NSCondition我已經註釋了。
執行緒的順序執行
他們都可以通過
[ticketsCondition signal]; 傳送訊號的方式,在一個執行緒喚醒另外一個執行緒的等待。
比如:
- #import "AppDelegate.h"
- #import "ViewController.h"
- @implementation AppDelegate
- - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
- {
- tickets = 100;
- count = 0;
- theLock = [[NSLock alloc] init];
- // 鎖物件
- ticketsCondition = [[NSCondition alloc] init];
- ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
- [ticketsThreadone setName:@"Thread-1"];
- [ticketsThreadone start];
- ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
- [ticketsThreadtwo setName:@"Thread-2"];
- [ticketsThreadtwo start];
- NSThread *ticketsThreadthree = [[NSThread alloc] initWithTarget:self selector:@selector(run3) object:nil];
- [ticketsThreadthree setName:@"Thread-3"];
- [ticketsThreadthree start];
- self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
- // Override point for customization after application launch.
- self.viewController = [[ViewController alloc] initWithNibName:@"ViewController" bundle:nil];
- self.window.rootViewController = self.viewController;
- [self.window makeKeyAndVisible];
- return YES;
- }
- -(void)run3{
- while (YES) {
- [ticketsCondition lock];
- [NSThread sleepForTimeInterval:3];
- [ticketsCondition signal];
- [ticketsCondition unlock];
- }
- }
- - (void)run{
- while (TRUE) {
- // 上鎖
- [ticketsCondition lock];
- [ticketsCondition wait];
- [theLock lock];
- if(tickets >= 0){
- [NSThread sleepForTimeInterval:0.09];
- count = 100 - tickets;
- NSLog(@"當前票數是:%d,售出:%d,執行緒名:%@",tickets,count,[[NSThread currentThread] name]);
- tickets--;
- }else{
- break;
- }
- [theLock unlock];
- [ticketsCondition unlock];
- }
- }
其他同步
我們可以使用指令 @synchronized 來簡化 NSLock的使用,這樣我們就不必顯示編寫建立NSLock,加鎖並解鎖相關程式碼。
- (void)doSomeThing:(id)anObj
{
@synchronized(anObj)
{
// Everything between the braces is protected by the @synchronized directive.
}
}
還有其他的一些鎖物件,比如:迴圈鎖NSRecursiveLock,條件鎖NSConditionLock,分散式鎖NSDistributedLock等等,可以自己看官方文件學習
NSThread下載圖片的例子程式碼:http://download.csdn.net/detail/totogo2010/4591149
著作權宣告:本文由http://blog.csdn.net/totogo2010/原創,歡迎轉載分享。請尊重作者勞動,轉載時保留該宣告和作者部落格連結,謝謝!
相關文章
- iOS 多執行緒之NSThreadiOS執行緒thread
- ios多執行緒程式設計(NSThread)(NSOperation )(GCD)iOS執行緒程式設計threadGC
- iOS多執行緒--NSThreadiOS執行緒thread
- iOS多執行緒程式設計技術之NSThread、Cocoa NSOperation、GCDiOS執行緒程式設計threadGC
- iOS多執行緒NSThread篇iOS執行緒thread
- iOS 多執行緒之NSThread和NSObjectiOS執行緒threadObject
- iOS多執行緒講解一之NSThreadiOS執行緒thread
- iOS多執行緒之併發程式設計-4iOS執行緒程式設計
- iOS多執行緒程式設計之NSOperation和NSOperationQueue的使用iOS執行緒程式設計
- IOS多執行緒程式設計:概述iOS執行緒程式設計
- 執行緒2--多執行緒NSThread執行緒thread
- iOS多執行緒程式設計:執行緒同步總結iOS執行緒程式設計
- iOS多執行緒(Pthread、NSThread、GCD、NSOperation)iOS執行緒threadGC
- iOS多執行緒程式設計入門iOS執行緒程式設計
- NSThread與多執行緒操作thread執行緒
- NSThread實現多執行緒thread執行緒
- NSThread多執行緒實現thread執行緒
- 多執行緒程式設計基礎(一)-- 執行緒的使用執行緒程式設計
- IOS高階程式設計之三:IOS 多執行緒程式設計iOS程式設計執行緒
- 使用執行緒池優化多執行緒程式設計執行緒優化程式設計
- iOS多執行緒:『pthread、NSThread』詳盡總結iOS執行緒thread
- iOS多執行緒程式設計總結(上)iOS執行緒程式設計
- iOS多執行緒程式設計總結(中)iOS執行緒程式設計
- iOS多執行緒程式設計總結(下)iOS執行緒程式設計
- 多執行緒程式設計基礎(二)-- 執行緒池的使用執行緒程式設計
- iOS 多執行緒之執行緒安全iOS執行緒
- iOS多執行緒之執行緒安全iOS執行緒
- 多執行緒(pthread,NSThread,GCD)執行緒threadGC
- iOS多執行緒程式設計之Grand Central Dispatch(GCD)介紹和使用iOS執行緒程式設計GC
- 多執行緒程式設計執行緒程式設計
- iOS多執行緒的使用iOS執行緒
- 深入淺出Win32多執行緒程式設計--之MFC的多執行緒Win32執行緒程式設計
- iOS多執行緒程式設計三:Operation和OperationQueueiOS執行緒程式設計
- C語言 之 多執行緒程式設計C語言執行緒程式設計
- 執行緒和程式基礎以及多執行緒的基本使用(iOS)執行緒iOS
- IOS多執行緒之(GCD)iOS執行緒GC
- iOS 多執行緒之GCDiOS執行緒GC
- JavaScript多執行緒程式設計JavaScript執行緒程式設計