91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

iOS使用多線程提高數據并發訪問 之五

發布時間:2020-07-06 10:47:03 來源:網絡 閱讀:761 作者:iKingLai 欄目:移動開發

你的線程入口


當啟動線程時,你需要有一些代碼來管理當前線程的狀態,線程創建和執行的內存,還有在線程內部拋出的異常。原因是你新創建的線程會有自己的棧,它和默認的棧是不同的,如圖 6-4。因此,你線程使用的內存和主線程使用的內存是不同的。異常也類似;它只會存儲在你的棧中,并不會返回到主棧和主線程中。


iOS使用多線程提高數據并發訪問 之五

有很多事情你需要記住:

  • Autorelease pool:管理autorelease對象

  • ExceptionHandler:管理線程運行過程中發生的異常

  • RunLoop:創建事件處理代碼


我會討論為什么要實現他們已經如何實現他們。


表格6-3 提供了一個簡短的演示,讓你復習一下創建和配置線程的主要技術,以及他們的優缺點。

iOS使用多線程提高數據并發訪問 之五

Autorelease Pool


在應用的每一個線程中,你應該總是要有一個Autorelease Pool,通過把代碼放在@autorelease中塊中。這個pool會包含所有的autoreleased對象,當線程運行的時候。如果你沒有調用返回一個autoreleased對象的方法,最好還是包含@autorelease,因為系統底層的frameworks和libraries也會創建和返回autoreleased對象。如果你有一個@autorelease,而從沒使用它,一切依然能夠正常運行。


如果你通過Xcode模板創建的應用,你會看到main方法中有下面的代碼:


int main(int argc, char *argv[]) {

   @autoreleasepool {

           int retVal = UIApplicationMain(argc, argv, nil, nil);

   }

   return retVal;

}


@autorelease將會處理線程內部所有的autoreleased對象。你可能已經知道,autoreleased對象是

一個你不再使用的,但是你又不想立即釋放的對象。它同樣可以使用類似[NSMutableArray array]這樣的工廠方法來返回一個autorelease對象;。這些對象將在run loop結束時被release。


因此,如果你創建了一個新的線程,確保你的代碼包裹在@autorelease塊中,像這樣:


- (void)myThreadMethod {

       @autoreleasepool { // Top-level pool

       // Do thread work here.

       }

}


ExceptionHandler


在處理線程時,異常是非常重要的。因為每一個線程都有它自己的棧,當發生一個異常時,它將會跟蹤所有的方法直到棧的頂部。這可能導致你的線程停止運行。任何主線程中的exception handler將會被忽略。


下面是一個處理異常的基本代碼:


NSObject *myObject = nil;

@try {

   // access to some objects inside an array

   myObject = [myArray objectAtIndex:2];

}

@catch ( NSException *e ) {

       NSLog(@"Array has fewer than 3 items");

}

@finally {
       // clean up code here

}


Run Loop


當你創建一個新的線程后,你有兩種方法來執行它。

  • 在線程內部編寫代碼來執行你的邏輯,直到任務執行完畢,而沒有什么中斷。比如,之前介紹過的從URL現在圖片的代碼。顯然,這是比較簡單的。

  • 當有動態事件發生時,你想要你的線程做出響應。比如監聽網絡上的socket或在某個特定時間觸發的事件。這和第一種情況是不同的,需要你在創建一個新的run loop。


下面是一個簡單的代碼,在一個RunLoop中監聽一個輸入流:


  1. NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
    [iStream setDelegate:self];
    [iStream scheduleInRunLoop:runLoop forMode:NSDefaultRunLoopMode];



注意:如果[NSRunLoop currentRunLoop]方法是在一個線程中調用,而不是一個run loop,這個方法創建一個新的run loop。



如果你想要在開始運行之前,讓一個run loop來等待一段時間,你可以使用NSTimer:


  1. [NSTimer scheduledTimerWithTimeInterval:2.0target:self

    selector:@selector(doStuff)userInfo:nil

    repeats:YES];


但是,有些情況你不應該使用RunLoop,比如在主線程中你有事件處理代碼,如NSInputStream或NSTimer工作在一些敏感的任務上,要花費很長的時間才能完成。因為事件處理代碼,像我的這個例子,最終會運行在創建它的線程上,你的線程不能繼續運行其他事件處理代碼,直到舊的事件處理完畢。這對UI主線程是非常有害的,如果你在線程內部創建了timer或input stream run loop。主要的問題是它使得你的UI變得更不靈敏。





向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

潮安县| 石林| 台江县| 汝南县| 昌平区| 辽阳市| 四平市| 常州市| 南投市| 绿春县| 蓝山县| 平定县| 贡觉县| 平度市| 望奎县| 贵南县| 随州市| 黔南| 南安市| 阜新| 慈溪市| 昆明市| 嘉善县| 启东市| 四会市| 贵港市| 博湖县| 乌兰察布市| 中江县| 新晃| 合作市| 延边| 萨迦县| 汨罗市| 开封市| 三门峡市| 巫溪县| 合江县| 荆门市| 大石桥市| 库尔勒市|