日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

ios runloop学习

發(fā)布時間:2025/3/17 编程问答 29 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ios runloop学习 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

今天突然才之間才意識到NSTimer這樣的運行方式,是在多線程中實現的循環(huán)還是在主線程中去實現的呢。當然不可能是在主線程中的while那么簡單,那樣什么都干不了,簡單看了下NSTimer是以同步方式運行的。時間到了,消息發(fā)出后,ontimer的函數是在主線程上調用的。

我們會經常看到這樣的代碼:

  • - (IBAction)start:(id)sender??
  • {??
  • pageStillLoading = YES;??
  • [NSThread detachNewThreadSelector:@selector(loadPageInBackground:)toTarget:self withObject:nil];??
  • [progress setHidden:NO];??
  • while (pageStillLoading) {??
  • [NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];??
  • }??
  • [progress setHidden:YES];??
  • }??
  • 復制代碼

    這段代碼很神奇的,因為他會“暫停”代碼運行,而且程序運行不會因為這里有一個while循環(huán)而受到影響。在[progress setHidden:NO]執(zhí)行之后,整個函數想暫停了一樣停在循環(huán)里面,等loadPageInBackground里面的操作都完成了以后才讓[progress setHidden:YES]運行。這樣做就顯得簡介,而且邏輯很清晰。如果你不這樣做,你就需要在loadPageInBackground里面表示load完成的地方調用[progress setHidden:YES],顯得代碼不緊湊而且容易出錯。

    ?

    ? ? ? ? Run loop就像它的名字一樣,是你thread中的一個循環(huán)并對收到的事件進行處理。你的代碼提供控制語句用來對run loop進行執(zhí)行——換句話說:你的代碼提供while或for循環(huán)來驅動run loop。在你的循環(huán)中,你使用run loop對象來“運行”事件處理代碼。事件處理代碼主要進行接收事件并調用事件處理函數。

    ??????? Run loop從兩個不同的事件源中接收消息。Input sources(CFRunLoopSource)投遞異步消息,通常來自于另一個thread或另一個應用程序。Timer sources(CFRunLoopTimer)當在計劃的時間或重復的時間間隔內投遞同步消息。兩種事件源都使用應用程序指定的處理方式對到達的事件進行處理。下圖展示了run loop和不同的事件源結構。

    如果我們要寫多線程的程序,可能就需要自己來管理Run Loop。
    下面說一下樓主提出的方法中的參數:
    RunMode: NSDefaultRunLoopMode,可以把這個理解為一個”過濾器“,我們可以只對自己關心的事件進行監(jiān)視。一般NSDefaultRunLoopMode是最常用的。

    啟動run loop的方法就是lz寫的這個,它的說明如下:
    Runs the loop once, blocking for input in the specified mode until a given date.
    啟動run loop一次,在特定的run loop mode下等待輸入。

    如果沒有附加input source或是timer,或是過limitDate,run loop就會退出,并且方法返回NO。

    下來是Run Loop的使用場合:
    1. 使用port或是自定義的input source來和其他線程進行通信
    2. 在線程(非主線程)中使用timer
    3. 使用 performSelector…系列(如performSelectorOnThread, …)
    4. 使用線程執(zhí)行周期性工作

    run loop不需要創(chuàng)建,在線程中只需要調用[NSRunLoop currentRunLoop]就可以得到
    假設我們想要等待某個異步方法的回調。比如connection。如果我們的線程中沒有啟動run loop,是不會有效果的(因為線程已經運行完畢,正常退出了)。

    ?

    ?

    何時使用?Run Loop

    僅當在為你的程序創(chuàng)建輔助線程的時候,你才需要顯式運行一個 run loop。Run loop 是程序主線程基礎設施的關鍵部分。所以,Cocoa 和 Carbon 程序提供了代碼運 行主程序的循環(huán)并自動啟動 run loop。IOS 程序中 UIApplication 的 run 方法(或 Mac OS X 中的 NSApplication)作為程序啟動步驟的一部分,它在程序正常啟動的時 候就會啟動程序的主循環(huán)。類似的,RunApplicationEventLoop 函數為 Carbon 程序 啟動主循環(huán)。如果你使用 xcode 提供的模板創(chuàng)建你的程序,那你永遠不需要自己去顯 式的調用這些例程。

    對于輔助線程,你需要判斷一個 run loop 是否是必須的。如果是必須的,那么 你要自己配置并啟動它。你不需要在任何情況下都去啟動一個線程的 run loop。比 如,你使用線程來處理一個預先定義的長時間運行的任務時,你應該避免啟動 run loop。Run loop 在你要和線程有更多的交互時才需要,比如以下情況:

    ??使用端口或自定義輸入源來和其他線程通信???使用線程的定時器???Cocoa 中使用任何 performSelector...的方法???使線程周期性工作

    ?

    如果你決定在程序中使用 run loop,那么它的配置和啟動都很簡單。和所有線程 編程一樣,你需要計劃好在輔助線程退出線程的情形。讓線程自然退出往往比強制關 閉它更好。關于更多介紹如何配置和退出一個 run loop,參閱”使用 Run Loop 對象” 的介紹。

    ? ?上代碼:

    ?

    使用runloop阻塞線程的正確寫法

    Runloop可以阻塞線程,等待其他線程執(zhí)行后再執(zhí)行。

    比如:

    @implementation ViewController{
    ? ? BOOL end;
    }

    – (void)viewDidLoad
    {
    ? ? [super viewDidLoad];?
    ? ? NSLog(@”start new thread …”);
    ? ? [NSThread detachNewThreadSelector:@selector(runOnNewThread) toTarget:self withObject:nil];? ??
    ? ? while (!end) {
    ? ? ? ? NSLog(@”runloop…”);
    ? ? ? ? [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    ? ? ? ? NSLog(@”runloop end.”);
    ? ? }
    ? ? NSLog(@”ok.”);
    }
    -(void)runOnNewThread{
    ? ? ?NSLog(@”run for new thread …”);
    ? ? sleep(1);
    ? ? end=YES;
    ? ? NSLog(@”end.”);
    }

    但是這樣做,運行時會發(fā)現,while循環(huán)后執(zhí)行的語句會在很長時間后才被執(zhí)行。

    那是不是可以這樣:

    [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];

    縮短runloop的休眠時間,看起來解決了上面出現的問題。

    不過這樣也又問題,runloop對象被經常性的喚醒,這違背了runloop的設計初衷。runloop的作用就是要減少cpu做無謂的空轉,cpu可在空閑的時候休眠,以節(jié)約電量。

    那么怎么做呢?正確的寫法是:

    -(void)runOnNewThread{

    ? ? ?NSLog(@”run for new thread …”);
    ? ? sleep(1);
    ? ??[self performSelectorOnMainThread:@selector(setEnd) withObject:nil waitUntilDone:NO];
    ? ? NSLog(@”end.”);
    }
    -(void)setEnd{
    ? ? end=YES;
    }

    見黑體斜體字部分,要將直接設置變量,改為向主線程發(fā)送消息,執(zhí)行方法。問題得到解決。

    這里要說一下,造成while循環(huán)后語句延緩執(zhí)行的原因是,runloop未被喚醒。因為,改變變量的值,runloop對象根本不知道。延緩的時長總是不定的,這是因為,有其他事件在某個時點喚醒了主線程,這才結束了while循環(huán)。那么,向主線程發(fā)送消息,將喚醒runloop,因此問題就解決了。

    轉載于:https://www.cnblogs.com/yulang314/p/3550746.html

    總結

    以上是生活随笔為你收集整理的ios runloop学习的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    主站蜘蛛池模板: 久久久精品人妻一区二区三区四 | 银娇在线观看 | 久久国产视频一区 | 国产h自拍| 伊人干综合| 一级性生活黄色片 | 午夜爽视频| 国产精品高潮呻吟久久aⅴ码 | 免费av在线电影 | 亚洲无毛视频 | 熟妇人妻一区二区三区四区 | 亚洲色图一区二区 | 成人毛片100部免费看 | 美女视频久久久 | 午夜免费看视频 | 免费av电影网址 | 亚洲国产欧美视频 | 麻豆一级片 | 亚洲欧美日韩视频一区 | 日日夜精品| www夜插内射视频网站 | 欧美精品性视频 | 99久久精品一区 | 亚洲精品一区二区三区四区 | 在线观看视频你懂得 | 高清在线一区二区 | 麻豆一区二区 | 欧美天堂视频 | 美女av网 | 欧美激情偷拍 | 免费黄色av| 91午夜影院 | 亚洲三级黄色片 | 国产四区 | 国产免费麻豆 | 亚洲精品久久久久久无码色欲四季 | 99久久伊人 | 在线成人小视频 | 亚洲欧美日韩中文字幕在线观看 | 免费av在线网址 | 制服丝袜第二页 | 熟女少妇在线视频播放 | 国产精品国产三级国产专区52 | 日韩精品一区二区三区视频在线观看 | 无码国产精品一区二区免费16 | 少妇被狂c下部羞羞漫画 | 精品国产露脸精彩对白 | 91高清国产 | 免费av网页 | 久久久国产精品成人免费 | 特级西西人体444www高清 | 国产性70yerg老太 | 韩国av免费在线 | 欧美一区二区在线免费观看 | 久久高清一区 | 精品在线免费播放 | xx视频在线| 人妻洗澡被强公日日澡 | 在线欧美视频 | 国产a视频精品免费观看 | 久色免费视频 | 国产一线二线在线观看 | 99视频免费观看 | 天堂va蜜桃| 亚拍一区 | 无码h黄肉3d动漫在线观看 | 中文字幕免费视频 | 欧美手机在线观看 | 操操日| 亚洲av综合永久无码精品天堂 | 国产这里有精品 | 91超碰在线播放 | 久久少妇网 | 91丨九色丨蝌蚪丨丝袜 | 波多野结衣二区三区 | 第一福利在线视频 | 亚洲精品福利 | 伊人久久大香线蕉av色婷婷色 | 亚洲免费黄色网 | 欧美午夜久久 | 免费看一级一片 | 99久久人妻无码中文字幕系列 | 国产精品2区 | 欧美第二区| 在线免费观看视频黄 | 黄视频在线观看免费 | 91pao| 精品人妻伦一二三区久久 | 日本国产一区 | 超碰导航 | 免费在线观看污 | 国产成人无码aa精品一区 | 久久影院午夜理论片无码 | 国产无遮挡a片又黄又爽 | 91区 | 成人h视频在线 | 中文幕无线码中文字夫妻 | av在线入口 | 精品亚洲精品 |