多線程

一籍凝、多線程概述

程序周瞎、進(jìn)程、線程

程序:由源代碼生成的可執(zhí)行應(yīng)用(例如:QQ.app)

進(jìn)程:一個正在運行的程序可以看做一個進(jìn)程静浴。(例如:正在運行的 QQ就是一個進(jìn)程)堰氓,進(jìn)程擁有獨立運行所需的全部資源

線程:程序中獨立運行的代碼段。(例如:接收QQ消息的代碼)

一個進(jìn)程是由一或多個線程組成苹享。進(jìn)程只負(fù)責(zé)資源的調(diào)度和分配双絮,線程才是程序真正的執(zhí)行單元,負(fù)責(zé)代碼的執(zhí)行得问。

單線程

  • 每個正在運行的程序(即進(jìn)程)囤攀,至少包含一個線程,這個線程叫主線程宫纬。
  • 主線程在程序啟動時被創(chuàng)建焚挠,用于執(zhí)行main函數(shù)。
  • 只有一個線程即主線程的程序漓骚,稱作單線程程序蝌衔。
  • 在單線程程序中,主線程負(fù)責(zé)執(zhí)行程序的所有代碼(UI展現(xiàn)以及刷新蝌蹂,網(wǎng)絡(luò)請求噩斟,本地存儲等等)。這些代碼只能順序執(zhí)行孤个,無法并發(fā)執(zhí)行剃允。

多線程

  • 擁有多個線程的程序,稱作多線程程序。
  • iOS允許用戶自己開辟新的線程斥废,相對于主線程來講椒楣,這些線程,稱作子線程牡肉。
  • 可以根據(jù)需要開辟若干子線程
  • 子線程和主線程都是獨立的運行單元捧灰,各自的執(zhí)行互不影響,因此能夠并發(fā)執(zhí)行荚板。

單凤壁、多線程區(qū)別

  • 單線程程序:只有一個線程,即主線程跪另,代碼順序執(zhí)行,容易出現(xiàn)代碼阻塞(頁面假死)煤搜。
  • 多線程程序:有多個線程免绿,線程間獨立運行,能有效地避免代碼阻塞擦盾,并且提高程序的運行性能嘲驾。
  • 注意:iOS中關(guān)于UI的添加和刷新必須在主線程中操作。

二迹卢、iOS平臺下的多線程

iOS多線程實現(xiàn)種類

  • NSThread
  • NSOperationQueue
  • NSObject
  • GCD

---------------------NSThread和NSObject------------------

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    NSLog(@"測試");
    /*
    // 線程休眠5秒
    [NSThread sleepForTimeInterval:5.0];
    
    // [NSThread currentThread] 獲取當(dāng)前的線程
    NSLog(@"current ==== %@", [NSThread currentThread]);
    
    // [NSThread mainThread] 獲取主線程
    NSLog(@"main ==== %@", [NSThread mainThread]);
    
    // [NSThread isMainThread] 判斷當(dāng)前線程是否是主線程
    NSLog(@"isMainThread = %d", [NSThread isMainThread]);
   */
    
    // NSThread手動開辟子線程
    // 第一個參數(shù):target
    // 第二個參數(shù):action
    // 第三個參數(shù):傳參
//    NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(sayHi) object:nil];
    
    // 讓線程開始執(zhí)行
//    [thread start];
    
    // [thread isExecuting] 判斷一個線程是否正在執(zhí)行
//    NSLog(@"isExecuting = %d", [thread isExecuting]);
    
    // [thread isFinished] 判斷一個線程是否完成了任務(wù)(是否執(zhí)行完畢)
//    NSLog(@"isFinished = %d", [thread isFinished]);
    
    // 結(jié)束線程 給線程發(fā)送結(jié)束消息
//    [thread cancel];
    
    // NSThread自動開辟線程
//    [NSThread detachNewThreadSelector:@selector(sayHi) toTarget:self withObject:nil];
    
    // NSObject開辟子線程
    // 第一個參數(shù):selector辽故,子線程執(zhí)行的代碼
    // 第二個參數(shù):表示selector傳遞的參數(shù)
    // 這是NSObject中存在的后臺執(zhí)行的方法
    [self performSelectorInBackground:@selector(sayHi) withObject:nil];
    
    self.view.backgroundColor = [UIColor cyanColor];
    
}
- (void)sayHi
{
    NSLog(@"current ==== %@", [NSThread currentThread]);
    NSLog(@"main ==== %@", [NSThread mainThread]);
    
    for (int i = 0; i < 1000; i++)
    {
        NSLog(@"i ==== %d",i);
        if (i == 500)
        {
            // 立即結(jié)束線程
            // 寫在哪里 哪個線程就關(guān)閉了 注意:不要隨意地使用,使用時一定要注意當(dāng)前的線程是否是主線程
//            [NSThread exit];
        }
    }
    // NSObject中存在的回到主線程執(zhí)行的方法
    // 第一個參數(shù):回到主線程做的事情
    // 第二個參數(shù):傳遞的參數(shù)
    // 第三個參數(shù):直到當(dāng)前的線程已經(jīng)結(jié)束才去執(zhí)行這個方法
    [self performSelectorOnMainThread:@selector(onMainThread) withObject:nil waitUntilDone:YES];
}
- (void)onMainThread
{
    self.view.backgroundColor = [UIColor orangeColor];
    
    NSLog(@"current ==== %@", [NSThread currentThread]);
    
    NSLog(@"main ==== %@", [NSThread mainThread]);
    
    NSLog(@"isMainThread ==== %d", [NSThread isMainThread]);
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end

---------------NSOperation和NSOperationQueue-------------

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
    /*
     NSOperation類腐碱,在MVC中屬于M誊垢,是用來封裝單個任務(wù)相關(guān)的代碼和數(shù)據(jù)的抽象類
     因為它是抽象的,不能夠直接使用這個類症见,而是使用子類(NSInvocationOperation或NSBlockOperation)來執(zhí)行實際任務(wù)
     NSOperation(含子類)喂走,只是一個操作,本身無主線程谋作、子線程之分芋肠,可在任意線程中使用,它們本身和多線程沒有任何關(guān)系遵蚜,不會進(jìn)行線程的創(chuàng)建帖池,只是封裝了一定的代碼段和數(shù)據(jù)去實現(xiàn)一個功能。通常與NSOperationQueue結(jié)合使用
    */
    
    // NSInvocationOperation類封裝了執(zhí)行操作的target和要執(zhí)行的action
//    NSInvocationOperation *operation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(hehehe) object:nil];
    
    // 開始去執(zhí)行
//    [operation start];
    
    // NSBlockOperation封裝了需要執(zhí)行的代碼塊
//    NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
//        
//        NSLog(@"main1 ==== %@", [NSThread mainThread]);
//        NSLog(@"current1 ==== %@",[NSThread currentThread]);
//        
//    }];
    
    // 開始去執(zhí)行
//    [blockOperation start];
    
    /*
     NSOperationQueue是操作隊列吭净,它用來管理一組NSOperation對象的執(zhí)行睡汹,會根據(jù)需要自動為NSOperation開辟合適數(shù)量的線程,以完成任務(wù)的并行執(zhí)行
     在開發(fā)過程中攒钳,我們不需要管理線程的創(chuàng)建和銷毀
     NSOperation類可以調(diào)節(jié)它在隊列中的優(yōu)先級(使用addDependency:設(shè)置依賴關(guān)系)
     當(dāng)最大并發(fā)數(shù)設(shè)置為1的時候能實現(xiàn)線程同步(串行執(zhí)行)
    */
    
//    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
//    queue.maxConcurrentOperationCount = 2;
    
    // 給兩個NSOperation對象添加一個依賴關(guān)系帮孔,它們就會根據(jù)依賴關(guān)系順序執(zhí)行
//    [operation addDependency:blockOperation];
    
//    [queue addOperation:blockOperation];
//    [queue addOperation:operation];
    
    // 獲取系統(tǒng)提供的主隊列
//    NSOperationQueue *mainQueue = [NSOperationQueue mainQueue];
    
}
- (void)hehehe
{
    NSLog(@"main ==== %@", [NSThread mainThread]);
    NSLog(@"current ==== %@",[NSThread currentThread]);
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    queue.maxConcurrentOperationCount = 10;
    
    for (int i = 0; i < 10; i++)
    {
        NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
            
            NSLog(@"%dcurrent = %@, main = %@", i, [NSThread currentThread], [NSThread mainThread]);
        }];
        [queue addOperation:operation];
    }
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end

---------------GCD(Grand Central Dispatch)-----------------

GCD簡介

  • Grand Central Dispatch(GCD)是Apple開發(fā)的一種多核編程技術(shù)。主要用于優(yōu)化應(yīng)用程序以支持多核處理器以及其他對稱多處理系統(tǒng)

  • GCD提供函數(shù)實現(xiàn)多線程開發(fā),性能更高功能也更加強大

  • 它首次發(fā)布在Mac OS X10.6文兢,iOS4及以上也可用

GCD核心概念

  • 任務(wù):具有一定功能的代碼段晤斩。一般是一個block或者函數(shù)

  • 分發(fā)隊列:GCD以隊列的方式進(jìn)行工作,F(xiàn)IFO

  • GCD會根據(jù)分發(fā)隊列的類型姆坚,創(chuàng)建合適數(shù)量的線程執(zhí)行隊列中的任務(wù)

GCD中兩種隊列

dispatch queue分為下面2種:

  • SerialQueue:一次只執(zhí)行一個任務(wù)澳泵。Serial queue通常用于同步訪問特定的資源和數(shù)據(jù)。當(dāng)你創(chuàng)建多個Serial queue時兼呵,雖然它們各自是同步執(zhí)行的兔辅,但Serial queue與Serial queue之間是并發(fā)執(zhí)行的。SerialQueue能實現(xiàn)線程同步

  • Concurrent:可以并發(fā)地執(zhí)行多個任務(wù)击喂,但是遵守FIFO

GCD工程截圖.png

--------------------ViewController.m----------------------

#import "ViewController.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    
#pragma mark ---- GCD串行隊列
    
    // 系統(tǒng)提供的一個串行隊列
    // 里面的任務(wù)是在主線程依次去執(zhí)行维苔,也就是串行
    // 這個方法比較常用
//    dispatch_queue_t queue = dispatch_get_main_queue();
    
    // 創(chuàng)建一個串行隊列
    // 第一個參數(shù):隊列的名字(蘋果推薦使用反向域名去命名),也可以是0
    // 第二個參數(shù):系統(tǒng)提供好的一個宏懂昂,表示串行隊列系統(tǒng)保留字段
    // 這種方式創(chuàng)建的隊列介时,它會自己去開辟一個子線程去完成隊列里面的任務(wù)
//    dispatch_queue_t queue = dispatch_queue_create(0 , DISPATCH_QUEUE_SERIAL);
    
#pragma mark ---- 并行隊列
    
    // 使用系統(tǒng)提供的并行隊列
    // 這個方法比較常用
    // global queue 是蘋果里面的全局隊列,有4個優(yōu)先級
    // DISPATCH_QUEUE_PRIORITY_BACKGROUND 表示隊列的優(yōu)先級
    // 第二個參數(shù)是蘋果預(yù)留的參數(shù)凌彬,為了以后去使用沸柔,目前沒有用到,填寫0
//    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    
    // 自己創(chuàng)建一個并行隊列
    // 第一個參數(shù):表示這個隊列的名字
    // 第二個參數(shù):系統(tǒng)提供好的一個宏铲敛,表示并行隊列
//    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    
    // 使用dispatch_async向隊列中添加任務(wù)
//    dispatch_async(queue, ^{
//        
//    NSLog(@"main ==== %@褐澎,current ==== %@", [NSThread mainThread], [NSThread currentThread]);
//        
//    });
//    
//    dispatch_async(queue, ^{
//        
//        NSLog(@"main1 ==== %@,current1 ==== %@", [NSThread mainThread], [NSThread currentThread]);
//        
//    });
//    
//    dispatch_async(queue, ^{
//        
//        NSLog(@"main2 ==== %@伐蒋,current2 ==== %@", [NSThread mainThread], [NSThread currentThread]);
//        
//    });
//    
//    dispatch_async(queue, ^{
//        
//        NSLog(@"main3 ==== %@工三,current3 ==== %@", [NSThread mainThread], [NSThread currentThread]);
//        
//    });
//    
//    // 延遲執(zhí)行一段代碼 幾秒之后做某件事
//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5.0f * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//        
//        NSLog(@"已經(jīng)5秒之后了");
//        
//    });
    
#pragma mark ---- 重復(fù)的向一個隊列中添加一系列的任務(wù)
    
//    dispatch_queue_t queue = dispatch_queue_create(0, DISPATCH_QUEUE_CONCURRENT);
    // 使用dispatch_apply()往隊列中添加任務(wù),任務(wù)會重復(fù)執(zhí)行n次
    // 第一個參數(shù):執(zhí)行的次數(shù)
    // 第二個參數(shù):在哪個隊列里面去執(zhí)行
    // 第三個參數(shù):當(dāng)前索引
//    dispatch_apply(100, queue, ^(size_t index) {
//        
//        NSLog(@"index ==== %zu", index);
//        
//    });

#pragma mark ---- 分組
    
    // 創(chuàng)建一個分組
    // dispatch_group_t主要用于把一些不相關(guān)的任務(wù)歸為一組咽弦,組里面放的是隊列
//    dispatch_group_t group = dispatch_group_create();
    
    // 創(chuàng)建一個并行隊列
//    dispatch_queue_t queue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_CONCURRENT);
    
    // 將任務(wù)添加到隊列中徒蟆,此任務(wù)執(zhí)行的時候,其他任務(wù)停止執(zhí)行
//    dispatch_barrier_async(queue, ^{
//        
//        NSLog(@"我執(zhí)行時型型,其他任務(wù)停止執(zhí)行");
//        
//    });
    
    // dispatch_group_async作用是往組里面的隊列添加任務(wù)
    // 將任務(wù)添加到隊列中段审,并添加分組標(biāo)記
//    dispatch_group_async(group, queue, ^{
//        
//        NSLog(@"我是第1個任務(wù)");
//        
//    });
    
    // dispatch_group_notify作用:監(jiān)聽組里面的任務(wù),等到組里面的任務(wù)全部執(zhí)行完成之后闹蒜,才會執(zhí)行它里面的任務(wù)
    // 注意:在執(zhí)行dispatch_group_notify之前最起碼要向隊列中放置一個任務(wù)才可以寺枉,否則notify里面的任務(wù)不會等待小組里面的其他任務(wù)執(zhí)行完才執(zhí)行
//    dispatch_group_notify(group, queue, ^{
//        
//        NSLog(@"無論如何,我是最后一個");
//        
//    });
//    
//    dispatch_group_async(group, queue, ^{
//        
//        NSLog(@"我是第2個任務(wù)");
//        
//    });
//    
//    dispatch_group_async(group, queue, ^{
//        
//        NSLog(@"我是第3個任務(wù)");
//        
//    });
//    
//    dispatch_group_async(group, queue, ^{
//        
//        NSLog(@"我是第4個任務(wù)");
//        
//    });
    
    // dispatch_once() 將任務(wù)添加到隊列中绷落,但任務(wù)在程序運行過程中姥闪,只執(zhí)行一次
    // dispatch_sync() 將任務(wù)添加到隊列中block不執(zhí)行完,下面代碼不會執(zhí)行
    // dispatch_async_f() 將任務(wù)添加到隊列中砌烁,任務(wù)是函數(shù)非block
    
    /*
     dispatch_once:該函數(shù)接收一個dispatch_once用于檢查該代碼塊是否已經(jīng)被調(diào)度的謂詞(是一個長整形筐喳,實際上作為BOOL使用)催式。它還接收一個希望在應(yīng)用的生命周期內(nèi)僅被調(diào)度一次的代碼塊
     dispatch_once不僅意味著代碼僅會被運行一次而且還是線程安全的,這就意味著你不需要使用諸如@synchronized之類的來防止使用多個線程或者隊列時不同步的問題
    */
    
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0);
    
    // sync會等待block體執(zhí)行完成之后避归,才會去執(zhí)行block體外面的代碼
//    dispatch_sync(queue, ^{
//        
//        NSLog(@"第一個任務(wù)");
//        
//    });
//    NSLog(@"呵呵");
//    // async不等待block體執(zhí)行完就去執(zhí)行下面的代碼
//    dispatch_async(queue, ^{
//        
//        NSLog(@"第二個任務(wù)");
//        
//    });
//    NSLog(@"逗比");
    
    // 第一個參數(shù):隊列
    // 第二個參數(shù):函數(shù)參數(shù)的內(nèi)容
    // 第三個參數(shù):函數(shù)
    dispatch_async_f(queue, @"passValue", function);
}
void function(void * str)
{
    NSLog(@"這是一個函數(shù),%@",str);
}
- (void)loadData
{
    NSURLSession *session = [NSURLSession sharedSession];
    
    NSURLSessionTask *task = [session dataTaskWithURL:[NSURL URLWithString:@"https://www.baidu.com"] completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error == nil)
        {
            dispatch_async(dispatch_get_main_queue(), ^
            {
                //這里去做更新UI的事情
            });
        }
    }];
    [task resume];
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}
@end

-----------------------MyObject.h------------------------

#import <Foundation/Foundation.h>

@interface MyObject : NSObject

+(MyObject *)sharedMyObject;

@end

-----------------------MyObject.m-----------------------

#import "MyObject.h"

static MyObject *object = nil;

@implementation MyObject

+ (MyObject *)sharedMyObject
{
    static dispatch_once_t onceToke;
    // block中的代碼只會執(zhí)行一次
    dispatch_once(&onceToke, ^{
        
        if (object == nil)
    {
        object = [[MyObject alloc] init];
    }
        
    });
    return object;
}
@end
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末荣月,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子梳毙,更是在濱河造成了極大的恐慌哺窄,老刑警劉巖,帶你破解...
    沈念sama閱讀 219,188評論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件账锹,死亡現(xiàn)場離奇詭異萌业,居然都是意外死亡,警方通過查閱死者的電腦和手機奸柬,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,464評論 3 395
  • 文/潘曉璐 我一進(jìn)店門生年,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人廓奕,你說我怎么就攤上這事晶框。” “怎么了懂从?”我有些...
    開封第一講書人閱讀 165,562評論 0 356
  • 文/不壞的土叔 我叫張陵,是天一觀的道長蹲蒲。 經(jīng)常有香客問我番甩,道長,這世上最難降的妖魔是什么届搁? 我笑而不...
    開封第一講書人閱讀 58,893評論 1 295
  • 正文 為了忘掉前任缘薛,我火速辦了婚禮,結(jié)果婚禮上卡睦,老公的妹妹穿的比我還像新娘宴胧。我一直安慰自己,他們只是感情好表锻,可當(dāng)我...
    茶點故事閱讀 67,917評論 6 392
  • 文/花漫 我一把揭開白布恕齐。 她就那樣靜靜地躺著,像睡著了一般瞬逊。 火紅的嫁衣襯著肌膚如雪显歧。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,708評論 1 305
  • 那天确镊,我揣著相機與錄音士骤,去河邊找鬼。 笑死蕾域,一個胖子當(dāng)著我的面吹牛拷肌,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 40,430評論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼巨缘,長吁一口氣:“原來是場噩夢啊……” “哼添忘!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起带猴,我...
    開封第一講書人閱讀 39,342評論 0 276
  • 序言:老撾萬榮一對情侶失蹤昔汉,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后拴清,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體靶病,經(jīng)...
    沈念sama閱讀 45,801評論 1 317
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,976評論 3 337
  • 正文 我和宋清朗相戀三年口予,在試婚紗的時候發(fā)現(xiàn)自己被綠了娄周。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,115評論 1 351
  • 序言:一個原本活蹦亂跳的男人離奇死亡沪停,死狀恐怖煤辨,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情木张,我是刑警寧澤众辨,帶...
    沈念sama閱讀 35,804評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站舷礼,受9級特大地震影響鹃彻,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜妻献,卻給世界環(huán)境...
    茶點故事閱讀 41,458評論 3 331
  • 文/蒙蒙 一蛛株、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧育拨,春花似錦谨履、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,008評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至锹引,卻和暖如春矗钟,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背嫌变。 一陣腳步聲響...
    開封第一講書人閱讀 33,135評論 1 272
  • 我被黑心中介騙來泰國打工吨艇, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人腾啥。 一個月前我還...
    沈念sama閱讀 48,365評論 3 373
  • 正文 我出身青樓东涡,卻偏偏與公主長得像冯吓,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子疮跑,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,055評論 2 355

推薦閱讀更多精彩內(nèi)容

  • Object C中創(chuàng)建線程的方法是什么组贺?如果在主線程中執(zhí)行代碼,方法是什么祖娘?如果想延時執(zhí)行代碼失尖、方法又是什么渐苏? 1...
    AlanGe閱讀 1,740評論 0 17
  • 原文:http://www.cocoachina.com/ios/20170707/19769.html 本文主要...
    冬的天閱讀 2,279評論 0 12
  • 歡迎大家指出文章中需要改正或者需要補充的地方,我會及時更新全度,非常感謝。 一. 多線程基礎(chǔ) 1. 進(jìn)程 進(jìn)程是指在系...
    xx_cc閱讀 7,191評論 11 70
  • 知識點總結(jié) position三種形式 1.靜態(tài)定位 position:static; (標(biāo)準(zhǔn)流中的元素默認(rèn)形式...
    IT穎兒閱讀 409評論 0 0
  • 對于死亡的認(rèn)識,需要一個過程草娜。 開始的時候,死亡是游戲宰闰,死亡是犧牲,是處決解藻,是槍斃葡盗,更多的是在電影里看到的觅够,然后開...
    疏影0701閱讀 408評論 0 5