標籤:
#import "AppDelegate.h"@interface AppDelegate (){ NSInteger _totalTickests;}@property (nonatomic, retain) NSLock *lock;@end@implementation AppDelegate- (void)task1 { NSLog(@"當前線程:%@,是否是主線程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]); //當前任務在主線程中完成,未完成之前不會執行後面的代碼 for (long i = 0; i <= 10000000; i++) { NSLog(@"%ld",i); }}- (void)task2 { NSLog(@"當前線程:%@,是否是主線程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]); //當前任務在主線程中完成,未完成之前不會執行後面的代碼 for (long i = 0; i <= 100; i++) { NSLog(@"我是啦啦啦"); }}- (void)task3{ NSLog(@"嘎嘎嘎嘎嘎");}- (void)task4{ NSLog(@"藍歐4");}- (void)task5{ NSLog(@"iOS5");}/** * 系統預設在主線程中開啟事件迴圈,不斷地監聽使用者互動事件,但在子線程中沒有開啟時事件迴圈. runloop */- (void)startTime{ @autoreleasepool { //開啟定時器 [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(task3) userInfo:nil repeats:YES]; //在子線程中開啟事件迴圈,正是有了事件迴圈,定時器才能夠重複的執行任務. [[NSRunLoop currentRunLoop] run]; }}/* 程式:安裝在行動裝置上得每個應用,都是一個程式 進程:正在啟動並執行每一個應用程式就是一個進程,進程相當於一個任務. 線程:執行任務的單元片段叫做線程,也就是任務的真正執行者,只不過系統預設的把任務交給一個線程來做,則個線程就是主線程,為了提高使用者體驗,我們需要把耗時的操作交給子線程來做. *///買票- (void)sellTickets:(NSString *)name{ @autoreleasepool { while(YES){ [self.lock lock]; if (_totalTickests > 0) { //買票 _totalTickests--; NSLog(@"%@賣得票,剩餘票數%ld張",name, _totalTickests); }else{ NSLog(@"%@賣完了",name); break; } [self.lock unlock]; } }}//線程死結:臨界資源減少解鎖的過程,就容易造成死結,一個線程等待另一個線程釋放資源,但是,前一個線程缺少解鎖過程,造成後一個線程一直處於等待狀態//線程互斥:當多個線程訪問同一資源,一個線程訪問,其他線程應該等待,此時需要加鎖- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease]; //NSLog(@"當前線程:%@,是否是主線程:%d",[NSThread currentThread],[[NSThread currentThread] isMainThread]); //初始化票數 _totalTickests = 30; //建立鎖 self.lock = [[[NSLock alloc] init] autorelease]; //視窗1 [NSThread detachNewThreadSelector:@selector(sellTickets:) toTarget:self withObject:@"張好好"]; //視窗2 [NSThread detachNewThreadSelector:@selector(sellTickets:) toTarget:self withObject:@"金鳳"]; //[self task1]; //對於耗時的操作,交由子線程來完成,主線程依舊可以來處理使用者互動和介面的變化 //1.建立子線程第一種方式,使用線程類 NSThread //[NSThread detachNewThreadSelector:@selector(task1) toTarget:self withObject:nil]; //2.建立子線程第二種方式,使用線程類,需要手動開啟// NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(task1) object:nil];// // [thread start]; //開啟線程// // //釋放// [thread release]; //3.建立子線程第三種方式,使用NSObject 提供的方法 //[self performSelectorInBackground:@selector(downloadImage) withObject:nil]; //主線程定時器 //[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(task3) userInfo:nil repeats:YES]; //建立子線程,開啟定時器 //[self performSelectorInBackground:@selector(startTime) withObject:nil]; // UIImageView *imageView = [[UIImageView alloc] initWithFrame:[UIScreen mainScreen].bounds];// imageView.tag = 100;// imageView.backgroundColor = [UIColor cyanColor];// [self.window addSubview:imageView] ;// [imageView release]; //4.建立子線程第四種方式,建立愛你任務隊列,任務對列會為隊列中的任務,合理安排子線程來完成任務. //建立任務1 //NSInvocationOperation *op1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task4) object:nil]; // NSInvocationOperation *op2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task5) object:nil]; //建立任務2// NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{// for (int i = 0; i < 10; i++) {// NSLog(@"Frank is ....");// }// }];// // NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{// for (int i = 0; i < 10; i++) {// NSLog(@"你說啥..");// }// }]; //建立任務隊列,將任務添加到任務隊列中 //NSOperationQueue *quene = [[NSOperationQueue alloc] init];// //1.實現線程同步第一種方式,設定最大的並發數// [quene setMaxConcurrentOperationCount:1]; //2.實現線程同步的第二種方式,添加依賴關係 //[op2 addDependency:op1]; //[quene addOperation:op1]; //[quene addOperation:op2]; //釋放 //[op1 release]; //[op2 release]; //[quene release]; self.window.backgroundColor = [UIColor redColor]; [self.window makeKeyAndVisible]; return YES;}/** * 線程同步: 線程並發:任務與任務之間沒有先後關係,先執行的線程,有可能是最後一個完成的任務. *//** 主線程跳轉到子線程執行任務: 直接建立子線程, 執行對應的耗時的任務即可 子線程跳轉到主線程執行任務: 對於介面的重新整理操作, 交由主線程操作, 使用performSelectorOnMainThread::: 操作 *///下載圖片- (void)downloadImage{ //子線程沒有自動釋放池,遍曆構造器內部操作是autorelease來管理記憶體,因此需要自己添加自動釋放池 @autoreleasepool { [NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(task3) userInfo:nil repeats:YES]; //Get請求,同步串連 //1.建立網址字串對象 NSString *str = @"http://image.zcool.com.cn/56/13/1308200901454.jpg"; //2.建立NSURL對象 NSURL *url = [NSURL URLWithString:str]; //3.建立請求對象 NSURLRequest *request = [NSURLRequest requestWithURL:url]; //4.串連 NSData *data = [NSURLConnection sendSynchronousRequest:request returningResponse:nil error:nil]; UIImage *image = [UIImage imageWithData:data]; //如果要重新整理UI(介面),修改介面,應該交由主線程處理 //子線程跳轉到主線程中,執行任務 [self performSelectorOnMainThread:@selector(referenceUI:) withObject:image waitUntilDone:YES]; //waitUntilDone :是否等待完成 //如果多個參數,可以將多個參數放入字典或者數組中,withObject:給字典或者數組即可 } }- (void)referenceUI:(UIImage *)image{ UIImageView *imageView = (UIImageView *)[self.window viewWithTag:100]; imageView.image = image;}- (void)dealloc{ self.window = nil; self.lock = nil; [super dealloc];}@end
iOS中NSThread(主線程,子線程)