国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

多線程

2019-11-09 18:43:04
字體:
來源:轉載
供稿:網友

一個運行的程序就是一個進程或者叫做一個任務

一個進程至少包含一個線程,線程是程序的執行流

iOS 程序啟動時,在創建一個進程的同事,會開始運行一個程序,該程序被稱作主線程

主線程是其他線程最終的父線程,所有界面的顯示操作必須在主線程進行?。。?!

后臺線程無法更新UI界面和響應用戶點擊事件

系統中的每一個進程都是有自己獨立的虛擬內存空間,而同一個進程中的多個線程則公用進程的內存空間

每創建一個新的線程,都會消耗一定內存的CPU時間

當多線程對同一個資源出現爭奪的時候需要注意線程安全問題

線程的使用不是無節制的 :iOS 主線程的堆棧大小是1M,從第二個線程開始就是512KB,這些數值不能通過編譯器開關和線程API函數更改 

只有主線程有直接修改UI的能力

 

一、NSObject多線程方法

1、[NSThread currentThread]; 可以返回當前運行的線程

      num = 1 說明是主線程

      在任務多線程技術中,均可以使用此方法查看當前的線程情況。

2、新建后臺線程,調度任務

     [selfperformSelectorInBackground:@selector(bgTask)withObject:nil];

     使用performSelectorInBackground是可以修改UI的,不是強烈不建議這樣使用。

3、更新界面

     使用performSelectorOnMainThread可以在主線程上執行任務。

     提示:NSObject對象均可以調用此方法。

4、內存管理

     線程任務要包在@autoreleasepool(自動釋放池)中,否則容易引起內存泄露,而且非常難發現。

5、總結:使用簡單,量級輕,不能控制線程的執行順序

例如:

@implementation ViewController

- (void)viewDidLoad {

    [superviewDidLoad];

    UIButton *button1 =[UIButtonbuttonWithType:UIButtonTypeCustom];

    button1.backgroundColor =[UIColorredColor];

    button1.frame =CGRectMake(50,50, 100,50);

    [button1 setTitle:@"耗時操作"forState:UIControlStateNormal];

    [button1 addTarget:selfaction:@selector(buttton1)forControlEvents:UIControlEventTouchUpInside];

    [self.viewaddSubview:button1];

    UIButton *button2 =[UIButtonbuttonWithType:UIButtonTypeCustom];

    button2.backgroundColor =[UIColorredColor];

    button2.frame =CGRectMake(50,150, 100,50);

    [button2 setTitle:@"普通操作"forState:UIControlStateNormal];

    [button2 addTarget:selfaction:@selector(button2)forControlEvents:UIControlEventTouchUpInside];

    [self.viewaddSubview:button2];

}

-(void)buttton1

{

    //后臺耗時操作

    //performSelectorInBackground會創建一個后臺線程,并在該線程中執行調用的方法

//    performSelectorInBackground是可以修改UI的但是強烈不建議使用

    [selfperformSelectorInBackground:@selector(bgTask)withObject:nil];

}

-(void)button2

{

}

-(void)bgTask

{

    @autoreleasepool {

        for (int i =0; i  < 30000000; i++) {

            NSLog(@"%d",i);

        }

        //在主線程中修改所需要的操作或界面內容;withObject:所需要傳遞的參數

        [selfperformSelectorOnMainThread:@selector(change)withObject:nilwaitUntilDone:YES];

    }

}

-(void)change

{

}

二、NThread

 1、類方法

detachNewThreadSelector直接啟動線程,調用選擇器方法

2、成員方法

initWithTarget需要使用start方法才能啟動實例化出來的線程

優點:簡單

缺點:控制線程的生命周期比較困難

           控制并發線程數

           先后順序困難

例如:

#import "ViewController.h"

@interface ViewController ()

@PRoperty(nonatomic,strong)NSSet *imageViewSet;

@end

@implementation ViewController

-(void)setUpUI{

    //實例化圖像視圖集合

    NSMutableSet *imageSet = [NSMutableSetsetWithCapacity:28];

    NSInteger w =self.view.frame.size.width/8;

    NSInteger h =self.view.frame.size.height/8;

    for (int row =0; row < 7; row++) {

        for (int col =0; col < 4; col++) {

            //計算圖片的位置

            NSInteger x = col * w;

            NSInteger y = row * h;

            UIImageView *imageview =[[UIImageViewalloc]initWithFrame:CGRectMake(x, y, w, h)];

            //順序填充圖片

            NSInteger num = (row *4 * col) % 17 +1;

            NSString *imageName =[NSStringstringWithFormat:@"圖片名稱%ld",num];

            UIImage *image = [UIImageimageNamed:imageName];

            [imageview setImage:image];

            [self.viewaddSubview:imageview];

            [imageSet addObject:imageview];

            

        }

    }

    self.imageViewSet = imageSet;

    //添加按鈕

    UIButton *button =[UIButtonbuttonWithType:UIButtonTypeRoundedRect];

    [button setFrame:CGRectMake(110,self.view.frame.size.height - 80, 100,50)];

    [button setTitle:@"刷新圖片"forState:UIControlStateNormal];

    [button addTarget:selfaction:@selector(click)forControlEvents:UIControlEventTouchUpInside];

    [self.viewaddSubview:button];

    

}

-(void)click

{

    [selfthreadLoad];

}

#pragma mark - NSThread方法

-(void)threadLoadImage:(UIImageView *)imageView{

    @autoreleasepool {

        NSInteger num =arc4random_uniform(17) +1;

        NSString *imageName = [NSStringstringWithFormat:@"圖片名稱%ld",num];

        UIImage *image =[UIImageimageNamed:imageName];

        //主線程更新UI

        [imageView performSelectorOnMainThread:@selector(setImage:)withObject:image waitUntilDone:YES];

      

    }

   

}

-(void)threadLoad

{

    for (UIImageView *imagevin self.imageViewSet) {

        //新建線程調用threadLoadImage方法

//        [NSThread detachNewThreadSelector:@selector(threadLoadImage:) toTarget:self withObject:imagev];

        NSThread *thread = [[NSThreadalloc]initWithTarget:selfselector:@selector(threadLoadImage:)object:imagev];

        //啟動線程

        [thread start];

    }

}

- (void)viewDidLoad {

    [superviewDidLoad];

    

    [selfsetUpUI];

    

}

三、NSOperation

1、NSOperation的兩個子類NSInvocationOperation,NSBlockOperation

例如:

#import "ViewController.h"

@interface ViewController ()

@property(nonatomic,strong)NSSet *imageViewSet;

@property(strong,nonatomic)NSOperationQueue *queue;

@end

@implementation ViewController

-(void)setUpUI{

    //實例化圖像視圖集合

    NSMutableSet *imageSet = [NSMutableSetsetWithCapacity:28];

    NSInteger w =self.view.frame.size.width/8;

    NSInteger h =self.view.frame.size.height/8;

    for (int row =0; row < 7; row++) {

        for (int col =0; col < 4; col++) {

            //計算圖片的位置

            NSInteger x = col * w;

            NSInteger y = row * h;

            UIImageView *imageview =[[UIImageViewalloc]initWithFrame:CGRectMake(x, y, w, h)];

            //順序填充圖片

            NSInteger num = (row *4 * col) % 17 +1;

            NSString *imageName =[NSStringstringWithFormat:@"圖片名稱%ld",num];

            UIImage *image = [UIImageimageNamed:imageName];

            [imageview setImage:image];

            [self.viewaddSubview:imageview];

            [imageSet addObject:imageview];

            

        }

    }

    self.imageViewSet = imageSet;

    //添加按鈕

    UIButton *button =[UIButtonbuttonWithType:UIButtonTypeRoundedRect];

    [button setFrame:CGRectMake(110,self.view.frame.size.height - 80, 100,50)];

    [button setTitle:@"刷新圖片"forState:UIControlStateNormal];

    [button addTarget:selfaction:@selector(click)forControlEvents:UIControlEventTouchUpInside];

    [self.viewaddSubview:button];

    

    

}

-(void)click

{

   // [selfoperationLoad];

    [selfoperationBlockLoad];

}

#pragma mark - NSOperation方法

-(void)operationBlockLoad

{

    for (UIImageView *imagevin self.imageViewSet) {

    NSBlockOperation *op = [NSBlockOperationblockOperationWithBlock:^{

        [selfoperationLoadImage:imagev];

    }];

        [self.queueaddOperation:op];

    }

}

-(void)operationLoadImage:(UIImageView *)imageView{

    @autoreleasepool {

        NSInteger num =arc4random_uniform(17) +1;

        NSString *imageName = [NSStringstringWithFormat:@"圖片名稱%ld",num];

        UIImage *image =[UIImageimageNamed:imageName];

        //主線程更新UI

      [[NSOperationQueuemainQueue]addOperationWithBlock:^{

          [imageView setImage:image];

      }];

      

    }

   

}

-(void)operationLoad

{

    //隊列可以設置同時并發線程的數量

    [self.queuesetMaxConcurrentOperationCount:3];

    for (UIImageView *imagevin self.imageViewSet) {

        NSInvocationOperation *op =[[NSInvocationOperationalloc]initWithTarget:selfselector:@selector(operationLoadImage:)object:imagev];

        //如果直接調用start,實在主線程隊列上運行的,不會開啟新的線程

        [op start];

        //Invocation添加到隊列,一添加到隊列,就會開啟新的線程執行任務

        [self.queueaddOperation:op];

    }

}

#pragma mark - NSOperation操作之間的順序

-(void)operationDemo

{

    NSBlockOperation *op1 = [NSBlockOperationblockOperationWithBlock:^{

        

    }];

    NSBlockOperation *op2 = [NSBlockOperationblockOperationWithBlock:^{

        

    }];

    NSBlockOperation *op3 = [NSBlockOperationblockOperationWithBlock:^{

        

    }];

    //Dependency依賴依賴關系可以多重依賴

    [op2 addDependency:op1];

    [op3 addDependency:op2];

    [self.queueaddOperation:op3];

    [self.queueaddOperation:op1];

    [self.queueaddOperation:op2];

}

- (void)viewDidLoad {

    [superviewDidLoad];

    

    [selfsetUpUI];

    //實例化操作隊列

    self.queue = [[NSOperationQueuealloc]init];

    

}

四、GCD

#import "ViewController.h"

@interface ViewController ()

@property(nonatomic,strong)NSSet *imageViewSet;

@end

@implementation ViewController

-(void)setUpUI{

    //實例化圖像視圖集合

    NSMutableSet *imageSet = [NSMutableSetsetWithCapacity:28];

    NSInteger w =self.view.frame.size.width/8;

    NSInteger h =self.view.frame.size.height/8;

    for (int row =0; row < 7; row++) {

        for (int col =0; col < 4; col++) {

            //計算圖片的位置

            NSInteger x = col * w;

            NSInteger y = row * h;

            UIImageView *imageview =[[UIImageViewalloc]initWithFrame:CGRectMake(x, y, w, h)];

            //順序填充圖片

            NSInteger num = (row *4 * col) % 17 +1;

            NSString *imageName =[NSStringstringWithFormat:@"圖片名稱%ld",num];

            UIImage *image = [UIImageimageNamed:imageName];

            [imageview setImage:image];

            [self.viewaddSubview:imageview];

            [imageSet addObject:imageview];

            

        }

    }

    self.imageViewSet = imageSet;

    //添加按鈕

    UIButton *button =[UIButtonbuttonWithType:UIButtonTypeRoundedRect];

    [button setFrame:CGRectMake(110,self.view.frame.size.height - 80, 100,50)];

    [button setTitle:@"刷新圖片"forState:UIControlStateNormal];

    [button addTarget:selfaction:@selector(click)forControlEvents:UIControlEventTouchUpInside];

    [self.viewaddSubview:button];

    

    

}

-(void)click

{

    [selfgcdLoad];

    

}

#pragma mark - GCD加載圖像

-(void)gcdLoad

{

    //派發dispatch異步async執行,并發執行

    //PRIORITY優先級,一般選擇默認的即可

    //獲取全局隊列

    dispatch_queue_t queue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

           for (UIImageView *imagevin self.imageViewSet) {

               dispatch_async(queue, ^{

                   NSInteger num =arc4random_uniform(17) +1;

                   NSString *imageName = [NSStringstringWithFormat:@"圖片名稱%ld",num];

                   UIImage *image =[UIImageimageNamed:imageName];

                   //設置圖像,在主線程隊列設置UI

                   dispatch_async(dispatch_get_main_queue(), ^{

                       [imagev setImage:image];

                   });

               });

        }

  

}

#pragma mark - GCD

-(void)gcdDemo

{

    //全局隊列中調用異步任務開發時候不用考慮并發線程數量問題

//    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

//    dispatch_async(queue, ^{

//        

//    });

    //    dispatch_async(queue, ^{

    //

    //    });

    //    dispatch_async(queue, ^{

    //

    //    });

    //串行隊列,需要創建,不能夠get

    dispatch_queue_t queue =dispatch_queue_create("myQUeue",DISPATCH_QUEUE_SERIAL);

       dispatch_async(queue, ^{

    

        });

       dispatch_async(queue, ^{

        

       });

       dispatch_async(queue, ^{

        

       });

    

}

- (void)viewDidLoad {

    [superviewDidLoad];

    

    [selfsetUpUI];

    

}

@end


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 康乐县| 开鲁县| 柞水县| 大埔县| 桦甸市| 玛纳斯县| 札达县| 万安县| 东明县| 琼中| 哈尔滨市| 水城县| 曲阳县| 顺义区| 鸡泽县| 五华县| 信丰县| 乌拉特后旗| 安庆市| 特克斯县| 巩义市| 苏尼特右旗| 濉溪县| 尉氏县| 德昌县| 黑山县| 新龙县| 土默特左旗| 彭州市| 乡城县| 渭南市| 成安县| 石首市| 白玉县| 高安市| 奇台县| 乌审旗| 娄烦县| 内丘县| 买车| 邯郸县|