最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

淺析iOS應(yīng)用開發(fā)中線程間的通信與線程安全問題

 更新時(shí)間:2015年11月18日 09:27:35   作者:文頂頂  
這篇文章主要介紹了淺析iOS應(yīng)用開發(fā)中線程間的通信與線程安全問題,談到了包括互斥鎖的使用等設(shè)計(jì)要點(diǎn),需要的朋友可以參考下

線程間的通信
 
簡(jiǎn)單說明
線程間通信:在1個(gè)進(jìn)程中,線程往往不是孤立存在的,多個(gè)線程之間需要經(jīng)常進(jìn)行通信
 
線程間通信的體現(xiàn)
1個(gè)線程傳遞數(shù)據(jù)給另1個(gè)線程
在1個(gè)線程中執(zhí)行完特定任務(wù)后,轉(zhuǎn)到另1個(gè)線程繼續(xù)執(zhí)行任務(wù)
 
線程間通信常用方法

復(fù)制代碼 代碼如下:

- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait;

線程間通信示例 – 圖片下載

2015111892145343.png (600×346)

復(fù)制代碼 代碼如下:

//
//  YYViewController.m
//  06-NSThread04-線程間通信
//
//  Created by apple on 14-6-23.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYViewController.h"
@interface YYViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@end


復(fù)制代碼 代碼如下:

@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

// 在子線程中調(diào)用download方法下載圖片
    [self performSelectorInBackground:@selector(download) withObject:nil];
}

 

-(void)download
{
    //1.根據(jù)URL下載圖片
    //從網(wǎng)絡(luò)中下載圖片
    NSURL *urlstr=[NSURL URLWithString:@"fdsf"];

    //把圖片轉(zhuǎn)換為二進(jìn)制的數(shù)據(jù)
    NSData *data=[NSData dataWithContentsOfURL:urlstr];//這一行操作會(huì)比較耗時(shí)

    //把數(shù)據(jù)轉(zhuǎn)換成圖片
    UIImage *image=[UIImage imageWithData:data];
 
    //2.回到主線程中設(shè)置圖片
    [self performSelectorOnMainThread:@selector(settingImage:) withObject:image waitUntilDone:NO];
}

 

//設(shè)置顯示圖片
-(void)settingImage:(UIImage *)image
{
    self.iconView.image=image;
}

@end


代碼2:
復(fù)制代碼 代碼如下:

//
//  YYViewController.m
//  06-NSThread04-線程間通信
//
//  Created by apple on 14-6-23.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYViewController.h"
#import <NSData.h>

@interface YYViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *iconView;
@end


復(fù)制代碼 代碼如下:

@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
}

 
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
// 在子線程中調(diào)用download方法下載圖片

    [self performSelectorInBackground:@selector(download) withObject:nil];
}

 
-(void)download
{

    //1.根據(jù)URL下載圖片
    //從網(wǎng)絡(luò)中下載圖片
    NSURL *urlstr=[NSURL URLWithString:@"fdsf"];

    //把圖片轉(zhuǎn)換為二進(jìn)制的數(shù)據(jù)
    NSData *data=[NSData dataWithContentsOfURL:urlstr];//這一行操作會(huì)比較耗時(shí)

    //把數(shù)據(jù)轉(zhuǎn)換成圖片
    UIImage *image=[UIImage imageWithData:data];

    //2.回到主線程中設(shè)置圖片
    //第一種方式
//    [self performSelectorOnMainThread:@selector(settingImage:) withObject:image waitUntilDone:NO];

    //第二種方式
    //    [self.imageView performSelector:@selector(setImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:NO];

    //第三種方式
   [self.iconView performSelectorOnMainThread:@selector(setImage:) withObject:image waitUntilDone:NO];
}


//設(shè)置顯示圖片
//-(void)settingImage:(UIImage *)image
//{
//    self.iconView.image=image;
//}

@end

線程安全
 
一、多線程的安全隱患
資源共享
1塊資源可能會(huì)被多個(gè)線程共享,也就是多個(gè)線程可能會(huì)訪問同一塊資源
比如多個(gè)線程訪問同一個(gè)對(duì)象、同一個(gè)變量、同一個(gè)文件
當(dāng)多個(gè)線程訪問同一塊資源時(shí),很容易引發(fā)數(shù)據(jù)錯(cuò)亂和數(shù)據(jù)安全問題
示例一:

2015111892251282.png (664×387)

示例二:

2015111892312267.png (659×386)

問題代碼:

復(fù)制代碼 代碼如下:

//
//  YYViewController.m
//  05-線程安全
//
//  Created by apple on 14-6-23.
//  Copyright (c) 2014年 itcase. All rights reserved.
//


#import "YYViewController.h"

@interface YYViewController ()
//剩余票數(shù)

@property(nonatomic,assign) int leftTicketsCount;
@property(nonatomic,strong)NSThread *thread1;
@property(nonatomic,strong)NSThread *thread2;
@property(nonatomic,strong)NSThread *thread3;


@end


復(fù)制代碼 代碼如下:

@implementation YYViewController


- (void)viewDidLoad
{
    [super viewDidLoad];

    //默認(rèn)有20張票

    self.leftTicketsCount=10;

    //開啟多個(gè)線程,模擬售票員售票

    self.thread1=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];

    self.thread1.name=@"售票員A";

    self.thread2=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];

    self.thread2.name=@"售票員B";

    self.thread3=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];
    self.thread3.name=@"售票員C";
}

 
-(void)sellTickets
{
    while (1) {
        //1.先檢查票數(shù)
        int count=self.leftTicketsCount;
        if (count>0) {
            //暫停一段時(shí)間
            [NSThread sleepForTimeInterval:0.002];

            //2.票數(shù)-1
           self.leftTicketsCount= count-1;
 
            //獲取當(dāng)前線程
            NSThread *current=[NSThread currentThread];
            NSLog(@"%@--賣了一張票,還剩余%d張票",current,self.leftTicketsCount);
        }else
        {
            //退出線程
            [NSThread exit];
        }
    }
}


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{
    //開啟線程

   [self.thread1 start];
    [self.thread2 start];
    [self.thread3 start];

}

@end


打印結(jié)果:

2015111892340617.png (871×448)

二、安全隱患分析

2015111892405061.png (625×320)

2015111892430149.png (678×379)

三、如何解決
 
互斥鎖使用格式
@synchronized(鎖對(duì)象) { // 需要鎖定的代碼  }
注意:鎖定1份代碼只用1把鎖,用多把鎖是無效的
 
代碼示例:

復(fù)制代碼 代碼如下:

//
//  YYViewController.m
//  05-線程安全
//
//  Created by apple on 14-6-23.
//  Copyright (c) 2014年 itcase. All rights reserved.
//

#import "YYViewController.h"

@interface YYViewController ()

//剩余票數(shù)
@property(nonatomic,assign) int leftTicketsCount;
@property(nonatomic,strong)NSThread *thread1;
@property(nonatomic,strong)NSThread *thread2;
@property(nonatomic,strong)NSThread *thread3;
@end

@implementation YYViewController

- (void)viewDidLoad
{
    [super viewDidLoad];
    //默認(rèn)有20張票
    self.leftTicketsCount=10;
    //開啟多個(gè)線程,模擬售票員售票

    self.thread1=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];

    self.thread1.name=@"售票員A";

    self.thread2=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];

    self.thread2.name=@"售票員B";

    self.thread3=[[NSThread alloc]initWithTarget:self selector:@selector(sellTickets) object:nil];

    self.thread3.name=@"售票員C";
}


-(void)sellTickets
{
    while (1) {
        @synchronized(self){//只能加一把鎖
        //1.先檢查票數(shù)

        int count=self.leftTicketsCount;
        if (count>0) {
            //暫停一段時(shí)間
            [NSThread sleepForTimeInterval:0.002];
            //2.票數(shù)-1

           self.leftTicketsCount= count-1;
            //獲取當(dāng)前線程
            NSThread *current=[NSThread currentThread];
            NSLog(@"%@--賣了一張票,還剩余%d張票",current,self.leftTicketsCount);

        }else
        {
            //退出線程
            [NSThread exit];
        }
        }
    }
}


-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

    //開啟線程
   [self.thread1 start];
    [self.thread2 start];
    [self.thread3 start];
}

@end


執(zhí)行效果圖

2015111892457124.png (876×191)

互斥鎖的優(yōu)缺點(diǎn)
優(yōu)點(diǎn):能有效防止因多線程搶奪資源造成的數(shù)據(jù)安全問題
缺點(diǎn):需要消耗大量的CPU資源
 
互斥鎖的使用前提:多條線程搶奪同一塊資源
相關(guān)專業(yè)術(shù)語:線程同步,多條線程按順序地執(zhí)行任務(wù)
互斥鎖,就是使用了線程同步技術(shù)
 
四:原子和非原子屬性
 
OC在定義屬性時(shí)有nonatomic和atomic兩種選擇
atomic:原子屬性,為setter方法加鎖(默認(rèn)就是atomic)
nonatomic:非原子屬性,不會(huì)為setter方法加鎖
 
atomic加鎖原理

復(fù)制代碼 代碼如下:

@property (assign, atomic) int age;

- (void)setAge:(int)age
{

    @synchronized(self) {
       _age = age;
    }
}


原子和非原子屬性的選擇
nonatomic和atomic對(duì)比

  • atomic:線程安全,需要消耗大量的資源
  • nonatomic:非線程安全,適合內(nèi)存小的移動(dòng)設(shè)備 

iOS開發(fā)的建議

  • 所有屬性都聲明為nonatomic
  • 盡量避免多線程搶奪同一塊資源
  • 盡量將加鎖、資源搶奪的業(yè)務(wù)邏輯交給服務(wù)器端處理,減小移動(dòng)客戶端的壓力

相關(guān)文章

  • IOS開發(fā)中使用writeToFile時(shí)的注意事項(xiàng)

    IOS開發(fā)中使用writeToFile時(shí)的注意事項(xiàng)

    本篇文章主要介紹了開發(fā)中使用writeToFile時(shí)的注意事項(xiàng),具有很好的參考價(jià)值。下面跟著小編一起來看下吧
    2017-03-03
  • iOS視頻錄制(或選擇)壓縮及上傳功能(整理)

    iOS視頻錄制(或選擇)壓縮及上傳功能(整理)

    最新做的一個(gè)功能涉及到了視頻的錄制、壓縮及上傳功能,經(jīng)過大神的一番教導(dǎo),終于倒騰清楚了,今天小編把問題經(jīng)過記錄一下分享到腳本之家平臺(tái),供大家參考
    2017-03-03
  • iOS 中使用tableView實(shí)現(xiàn)右滑顯示選擇功能

    iOS 中使用tableView實(shí)現(xiàn)右滑顯示選擇功能

    這篇文章主要介紹了iOS 中使用tableView實(shí)現(xiàn)右滑顯示選擇功能的相關(guān)資料,非常不錯(cuò),具有參考借鑒價(jià)值,需要的朋友可以參考下
    2016-07-07
  • 個(gè)人對(duì)于異步和多線程的關(guān)系的理解分享

    個(gè)人對(duì)于異步和多線程的關(guān)系的理解分享

    異步和多線程并不是一個(gè)同等關(guān)系,異步是最終目的,多線程只是我們實(shí)現(xiàn)異步的一種手段。異步是當(dāng)一個(gè)調(diào)用請(qǐng)求發(fā)送給被調(diào)用者,而調(diào)用者不用等待其結(jié)果的返回而可以做其它的事情。
    2014-08-08
  • iOS CoreData 增刪改查詳解

    iOS CoreData 增刪改查詳解

    這篇文章主要為大家詳細(xì)介紹了iOS CoreData 增刪改查的相關(guān)資料,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2016-09-09
  • iOS13 適配和Xcode11.0踩坑小結(jié)

    iOS13 適配和Xcode11.0踩坑小結(jié)

    這篇文章主要介紹了iOS13 適配和Xcode11.0踩坑小結(jié),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-11-11
  • iOS實(shí)現(xiàn)多個(gè)垂直滑動(dòng)條并列視圖

    iOS實(shí)現(xiàn)多個(gè)垂直滑動(dòng)條并列視圖

    這篇文章主要為大家詳細(xì)介紹了iOS實(shí)現(xiàn)多個(gè)垂直滑動(dòng)條并列視圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03
  • iOS中使用UIDatePicker制作時(shí)間選擇器的實(shí)例教程

    iOS中使用UIDatePicker制作時(shí)間選擇器的實(shí)例教程

    這篇文章主要介紹了iOS中使用UIDatePicker制作時(shí)間選擇器的實(shí)例教程,實(shí)例中未選中的時(shí)間項(xiàng)目會(huì)講解一個(gè)將其變透明的方法,非常給力,需要的朋友可以參考下
    2016-05-05
  • iOS實(shí)現(xiàn)代碼只執(zhí)行一次

    iOS實(shí)現(xiàn)代碼只執(zhí)行一次

    本文給大家分享的是在iOS中控制代碼在整個(gè)軟件生命周期中只運(yùn)行一次的代碼,有需要的小伙伴可以參考下。
    2016-03-03
  • iOS開發(fā)技巧之WeakSelf宏的進(jìn)化詳解

    iOS開發(fā)技巧之WeakSelf宏的進(jìn)化詳解

    在程序中我們經(jīng)常用到Block,但寫weak self 時(shí)會(huì)比較繁瑣,下面這篇文章主要給大家介紹了關(guān)于iOS開發(fā)技巧之WeakSelf宏的進(jìn)化的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們一起來看看吧
    2018-05-05

最新評(píng)論

温泉县| 凉城县| 临夏县| 天镇县| 呼图壁县| 景德镇市| 康平县| 长沙县| 容城县| 三台县| 阿拉善左旗| 五指山市| 稷山县| 株洲县| 安平县| 崇明县| 海伦市| 盘锦市| 昌邑市| 长顺县| 金华市| 大竹县| 富平县| 吴忠市| 安新县| 邯郸市| 浦江县| 东乡族自治县| 曲松县| 隆化县| 农安县| 保山市| 彭山县| 阆中市| 长葛市| 莲花县| 云浮市| 永定县| 兴和县| 汝阳县| 德令哈市|