一区二区三区三上|欧美在线视频五区|国产午夜无码在线观看视频|亚洲国产裸体网站|无码成年人影视|亚洲AV亚洲AV|成人开心激情五月|欧美性爱内射视频|超碰人人干人人上|一区二区无码三区亚洲人区久久精品

電子發(fā)燒友App

硬聲App

0
  • 聊天消息
  • 系統(tǒng)消息
  • 評(píng)論與回復(fù)
登錄后你可以
  • 下載海量資料
  • 學(xué)習(xí)在線課程
  • 觀看技術(shù)視頻
  • 寫文章/發(fā)帖/加入社區(qū)
會(huì)員中心
創(chuàng)作中心

完善資料讓更多小伙伴認(rèn)識(shí)你,還能領(lǐng)取20積分哦,立即完善>

3天內(nèi)不再提示
創(chuàng)作
電子發(fā)燒友網(wǎng)>電子資料下載>電子資料>coobjc iOS協(xié)程開(kāi)發(fā)框架

coobjc iOS協(xié)程開(kāi)發(fā)框架

2022-06-24 | zip | 2.80 MB | 次下載 | 2積分

資料介紹

授權(quán)協(xié)議 Apache-2.0
開(kāi)發(fā)語(yǔ)言 Objective-C Swift
操作系統(tǒng) 跨平臺(tái)
軟件類型 開(kāi)源軟件
所屬分類 手機(jī)/移動(dòng)開(kāi)發(fā)、 手機(jī)開(kāi)發(fā)包

軟件簡(jiǎn)介

coobjc 為 Objective-C 和 Swift 提供了協(xié)程功能。coobjc 支持 await、generator 和 actor model,接口參考了 C#Javascript 和 Kotlin 中的很多設(shè)計(jì)。我們還提供了?cokit 庫(kù)為 Foundation 和 UIKit 中的部分 API 提供了協(xié)程化支持,包括 NSFileManager、JSON、NSData 與 UIImage 等。coobjc 也提供了元組的支持。

0x0 iOS 異步編程問(wèn)題

基于 Block 的異步編程回調(diào)是目前 iOS 使用最廣泛的異步編程方式,iOS 系統(tǒng)提供的 GCD 庫(kù)讓異步開(kāi)發(fā)變得很簡(jiǎn)單方便,但是基于這種編程方式的缺點(diǎn)也有很多,主要有以下幾點(diǎn):

  • 容易進(jìn)入"嵌套地獄"
  • 錯(cuò)誤處理復(fù)雜和冗長(zhǎng)
  • 容易忘記調(diào)用 completion handler
  • 條件執(zhí)行變得很困難
  • 從互相獨(dú)立的調(diào)用中組合返回結(jié)果變得極其困難
  • 在錯(cuò)誤的線程中繼續(xù)執(zhí)行
  • 難以定位原因的多線程崩潰
  • 鎖和信號(hào)量濫用帶來(lái)的卡頓、卡死

上述問(wèn)題反應(yīng)到線上應(yīng)用本身就會(huì)出現(xiàn)大量的多線程崩潰。

0x1 解決方案

上述問(wèn)題在很多系統(tǒng)和語(yǔ)言中都會(huì)遇到,解決問(wèn)題的標(biāo)準(zhǔn)方式就是使用協(xié)程。這里不介紹太多的理論,簡(jiǎn)單說(shuō)協(xié)程就是對(duì)基礎(chǔ)函數(shù)的擴(kuò)展,可以讓函數(shù)異步執(zhí)行的時(shí)候掛起然后返回值。協(xié)程可以用來(lái)實(shí)現(xiàn) generator ,異步模型以及其他強(qiáng)大的能力。

Kotlin 是這兩年由 JetBrains 推出的支持現(xiàn)代多平臺(tái)應(yīng)用的靜態(tài)編程語(yǔ)言,支持 JVM ,Javascript ,目前也可以在 iOS 上執(zhí)行,這兩年在開(kāi)發(fā)者社區(qū)中也是比較火。

在 Kotlin 語(yǔ)言中基于協(xié)程的 async/await ,generator/yield 等異步化技術(shù)都已經(jīng)成了語(yǔ)法標(biāo)配,Kotlin 協(xié)程相關(guān)的介紹,大家可以參考:https://www.kotlincn.net/docs/reference/coroutines/basics.html

0x2 協(xié)程

協(xié)程是一種在非搶占式多任務(wù)場(chǎng)景下生成可以在特定位置掛起和恢復(fù)執(zhí)行入口的程序組件

協(xié)程的概念在60年代就已經(jīng)提出,目前在服務(wù)端中應(yīng)用比較廣泛,在高并發(fā)場(chǎng)景下使用極其合適,可以極大降低單機(jī)的線程數(shù),提升單機(jī)的連接和處理能力,但是在移動(dòng)研發(fā)中,iOS和android目前都不支持協(xié)程的使用

0x3 coobjc 框架

coobjc 是由手機(jī)淘寶架構(gòu)團(tuán)隊(duì)推出的能在 iOS 上使用的協(xié)程開(kāi)發(fā)框架,目前支持 Objective-C 和 Swift 中使用,我們底層使用匯編和 C 語(yǔ)言進(jìn)行開(kāi)發(fā),上層進(jìn)行提供了 Objective-C 和 Swift 的接口,目前以 Apache 開(kāi)源協(xié)議進(jìn)行了開(kāi)源。

0x31 安裝

  • cocoapods 安裝:? pod 'coobjc'
  • 源碼安裝: 所有代碼在 ./coobjc 目錄下

0x32 文檔

0x33 特性

async/await

  • 創(chuàng)建協(xié)程

使用?co_launch?方法創(chuàng)建協(xié)程

co_launch(^{
    ...
});

co_launch?創(chuàng)建的協(xié)程默認(rèn)在當(dāng)前線程進(jìn)行調(diào)度

  • await 異步方法

在協(xié)程中我們使用 await 方法等待異步方法執(zhí)行結(jié)束,得到異步執(zhí)行結(jié)果

- (void)viewDidLoad{
    ...
		co_launch(^{
    		NSData *data = await(downloadDataFromUrl(url));
    		UIImage *image = await(imageFromData(data));
    		self.imageView.image = image;
		});
}

上述代碼將原本需要?dispatch_async?兩次的代碼變成了順序執(zhí)行,代碼更加簡(jiǎn)潔

  • 錯(cuò)誤處理

在協(xié)程中,我們所有的方法都是直接返回值的,并沒(méi)有返回錯(cuò)誤,我們?cè)趫?zhí)行過(guò)程中的錯(cuò)誤是通過(guò)?co_getError()?獲取的,比如我們有以下從網(wǎng)絡(luò)獲取數(shù)據(jù)的接口,在失敗的時(shí)候, promise 會(huì)?reject:error

- (CCOPromise*)co_GET:(NSString*)url
  parameters:(NSDictionary*)parameters{
    CCOPromise *promise = [CCOPromise promise];
    [self GET:url parameters:parameters progress:nil success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        [promise fulfill:responseObject];
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        [promise reject:error];
    }];
    return promise;
}

那我們?cè)趨f(xié)程中可以如下使用:

co_launch(^{
    id response = await([self co_GET:feedModel.feedUrl parameters:nil]);
    if(co_getError()){
        //處理錯(cuò)誤信息
    }
    ...
});

生成器

  • 創(chuàng)建生成器

我們使用?co_sequence?創(chuàng)建生成器

COCoroutine *co1 = co_sequence(^{
            int index = 0;
            while(co_isActive()){
                yield_val(@(index));
                index++;
            }
        });

在其他協(xié)程中,我們可以調(diào)用?next?方法,獲取生成器中的數(shù)據(jù)

co_launch(^{
            for(int i = 0; i < 10; i++){
                val = [[co1 next] intValue];
            }
        });
  • 使用場(chǎng)景

生成器可以在很多場(chǎng)景中進(jìn)行使用,比如消息隊(duì)列、批量下載文件、批量加載緩存等:

int unreadMessageCount = 10;
NSString *userId = @"xxx";
COSequence *messageSequence = sequenceOnBackgroundQueue(@"message_queue", ^{
   //在后臺(tái)線程執(zhí)行
    while(1){
        yield(queryOneNewMessageForUserWithId(userId));
    }
});

//主線程更新UI
co(^{
   for(int i = 0; i < unreadMessageCount; i++){
       if(!isQuitCurrentView()){
           displayMessage([messageSequence take]);
       }
   }
});

通過(guò)生成器,我們可以把傳統(tǒng)的生產(chǎn)者加載數(shù)據(jù)->通知消費(fèi)者模式,變成消費(fèi)者需要數(shù)據(jù)->告訴生產(chǎn)者加載模式,避免了在多線程計(jì)算中,需要使用很多共享變量進(jìn)行狀態(tài)同步,消除了在某些場(chǎng)景下對(duì)于鎖的使用

Actor

_ Actor 的概念來(lái)自于 Erlang ,在 AKKA 中,可以認(rèn)為一個(gè) Actor 就是一個(gè)容器,用以存儲(chǔ)狀態(tài)、行為、Mailbox 以及子 Actor 與 Supervisor 策略。Actor 之間并不直接通信,而是通過(guò) Mail 來(lái)互通有無(wú)。_

  • 創(chuàng)建 actor

我們可以使用?co_actor_onqueue?在指定線程創(chuàng)建 actor

CCOActor *actor = co_actor_onqueue(^(CCOActorChan *channel) {
    ...  //定義 actor 的狀態(tài)變量
    for(CCOActorMessage *message in channel){
        ...//處理消息
    }
}, q);
  • 給 actor 發(fā)送消息

actor 的?send?方法可以給 actor 發(fā)送消息

CCOActor *actor = co_actor_onqueue(^(CCOActorChan *channel) {
    ...  //定義actor的狀態(tài)變量
    for(CCOActorMessage *message in channel){
        ...//處理消息
    }
}, q);

// 給actor發(fā)送消息
[actor send:@"sadf"];
[actor send:@(1)];

元組

  • 創(chuàng)建元組

使用?co_tuple?方法來(lái)創(chuàng)建元組

COTuple *tup = co_tuple(nil, @10, @"abc");
NSAssert(tup[0] == nil, @"tup[0] is wrong");
NSAssert([tup[1] intValue] == 10, @"tup[1] is wrong");
NSAssert([tup[2] isEqualToString:@"abc"], @"tup[2] is wrong");

可以在元組中存儲(chǔ)任何數(shù)據(jù)

  • 元組取值

可以使用?co_unpack?方法從元組中取值

id val0;
NSNumber *number = nil;
NSString *str = nil;
co_unpack(&val0, &number, &str) = co_tuple(nil, @10, @"abc");
NSAssert(val0 == nil, @"val0 is wrong");
NSAssert([number intValue] == 10, @"number is wrong");
NSAssert([str isEqualToString:@"abc"], @"str is wrong");

co_unpack(&val0, &number, &str) = co_tuple(nil, @10, @"abc", @10, @"abc");
NSAssert(val0 == nil, @"val0 is wrong");
NSAssert([number intValue] == 10, @"number is wrong");
NSAssert([str isEqualToString:@"abc"], @"str is wrong");

co_unpack(&val0, &number, &str, &number, &str) = co_tuple(nil, @10, @"abc");
NSAssert(val0 == nil, @"val0 is wrong");
NSAssert([number intValue] == 10, @"number is wrong");
NSAssert([str isEqualToString:@"abc"], @"str is wrong");

NSString *str1;

co_unpack(nil, nil, &str1) = co_tuple(nil, @10, @"abc");
NSAssert([str1 isEqualToString:@"abc"], @"str1 is wrong");
  • 在協(xié)程中使用元組

首先創(chuàng)建一個(gè) promise 來(lái)處理元組里的值

COPromise*
cotest_loadContentFromFile(NSString *filePath){
    return [COPromise promise:^(COPromiseFullfill  _Nonnull resolve, COPromiseReject  _Nonnull reject) {
        if ([[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
            NSData *data = [[NSData alloc] initWithContentsOfFile:filePath];
            resolve(co_tuple(filePath, data, nil));
        }
        else{
            NSError *error = [NSError errorWithDomain:@"fileNotFound" code:-1 userInfo:nil];
            resolve(co_tuple(filePath, nil, error));
        }
    }];
}

然后,你可以像下面這樣獲取元組里的值:

co_launch(^{
    NSString *tmpFilePath = nil;
    NSData *data = nil;
    NSError *error = nil;
    co_unpack(&tmpFilePath, &data, &error) = await(cotest_loadContentFromFile(filePath));
    XCTAssert([tmpFilePath isEqualToString:filePath], @"file path is wrong");
    XCTAssert(data.length > 0, @"data is wrong");
    XCTAssert(error == nil, @"error is wrong");
});

使用元組你可以從?await?返回值中獲取多個(gè)值。

?

下載該資料的人也在下載 下載該資料的人還在閱讀
更多 >

評(píng)論

查看更多

下載排行

本周

  1. 1山景DSP芯片AP8248A2數(shù)據(jù)手冊(cè)
  2. 1.06 MB  |  532次下載  |  免費(fèi)
  3. 2RK3399完整板原理圖(支持平板,盒子VR)
  4. 3.28 MB  |  339次下載  |  免費(fèi)
  5. 3TC358743XBG評(píng)估板參考手冊(cè)
  6. 1.36 MB  |  330次下載  |  免費(fèi)
  7. 4DFM軟件使用教程
  8. 0.84 MB  |  295次下載  |  免費(fèi)
  9. 5元宇宙深度解析—未來(lái)的未來(lái)-風(fēng)口還是泡沫
  10. 6.40 MB  |  227次下載  |  免費(fèi)
  11. 6迪文DGUS開(kāi)發(fā)指南
  12. 31.67 MB  |  194次下載  |  免費(fèi)
  13. 7元宇宙底層硬件系列報(bào)告
  14. 13.42 MB  |  182次下載  |  免費(fèi)
  15. 8FP5207XR-G1中文應(yīng)用手冊(cè)
  16. 1.09 MB  |  178次下載  |  免費(fèi)

本月

  1. 1OrCAD10.5下載OrCAD10.5中文版軟件
  2. 0.00 MB  |  234315次下載  |  免費(fèi)
  3. 2555集成電路應(yīng)用800例(新編版)
  4. 0.00 MB  |  33566次下載  |  免費(fèi)
  5. 3接口電路圖大全
  6. 未知  |  30323次下載  |  免費(fèi)
  7. 4開(kāi)關(guān)電源設(shè)計(jì)實(shí)例指南
  8. 未知  |  21549次下載  |  免費(fèi)
  9. 5電氣工程師手冊(cè)免費(fèi)下載(新編第二版pdf電子書)
  10. 0.00 MB  |  15349次下載  |  免費(fèi)
  11. 6數(shù)字電路基礎(chǔ)pdf(下載)
  12. 未知  |  13750次下載  |  免費(fèi)
  13. 7電子制作實(shí)例集錦 下載
  14. 未知  |  8113次下載  |  免費(fèi)
  15. 8《LED驅(qū)動(dòng)電路設(shè)計(jì)》 溫德?tīng)栔?/a>
  16. 0.00 MB  |  6656次下載  |  免費(fèi)

總榜

  1. 1matlab軟件下載入口
  2. 未知  |  935054次下載  |  免費(fèi)
  3. 2protel99se軟件下載(可英文版轉(zhuǎn)中文版)
  4. 78.1 MB  |  537798次下載  |  免費(fèi)
  5. 3MATLAB 7.1 下載 (含軟件介紹)
  6. 未知  |  420027次下載  |  免費(fèi)
  7. 4OrCAD10.5下載OrCAD10.5中文版軟件
  8. 0.00 MB  |  234315次下載  |  免費(fèi)
  9. 5Altium DXP2002下載入口
  10. 未知  |  233046次下載  |  免費(fèi)
  11. 6電路仿真軟件multisim 10.0免費(fèi)下載
  12. 340992  |  191187次下載  |  免費(fèi)
  13. 7十天學(xué)會(huì)AVR單片機(jī)與C語(yǔ)言視頻教程 下載
  14. 158M  |  183279次下載  |  免費(fèi)
  15. 8proe5.0野火版下載(中文版免費(fèi)下載)
  16. 未知  |  138040次下載  |  免費(fèi)