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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 人文社科 > 生活经验 >内容正文

生活经验

2016 - 1- 21 - RunLoop使用(2016-1-24修改一次)(2016 - 1 - 24 再次修改)

發布時間:2023/11/27 生活经验 35 豆豆
生活随笔 收集整理的這篇文章主要介紹了 2016 - 1- 21 - RunLoop使用(2016-1-24修改一次)(2016 - 1 - 24 再次修改) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一:常駐線程 :當需要一個線程一直處理一些耗時操作時,可以讓它擁有一個RunLoop。具體代碼如下:

? ?1.通過給RunloopMode里加源來保證RunLoop不直接退出。 ?

? 這里有個很重要得知識點,runloop對象如果mode為空得話,會直接返回。在下面這段代碼中的run方法里:

    [[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];  // 給RunLoop的Mode里添加內容
    [[NSRunLoop currentRunLoop] run];// 開啟RunLoop,默認是出于Default模式。

? 保證RunLoop對象的mode不會為空,也就是不會直接退出,保證線程持續運行。

@interface ViewController ()
@property (nonatomic, strong) ZZThread *testThread;@end@implementation ViewController- (void)viewDidLoad {[super viewDidLoad];// 創建自己的線程,并讓其執行run方法ZZThread *thread = [[ZZThread alloc] initWithTarget:self selector:@selector(run) object:nil];self.testThread = thread;[self.testThread start];}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{[self performSelector:@selector(test) onThread:self.testThread withObject:nil waitUntilDone:NO ];
}
- (void)test{NSLog(@"%s ------- %@",__func__,[NSThread currentThread]);
}
// 給線程添加一個RunLoop 讓線程"Live"
- (void)run
{NSLog(@"%s -------------- %@",__func__,[NSThread currentThread]);// 如果RunLoop的Mode內沒有內容,RunLoop會被直接銷毀[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];  // 給RunLoop的Mode里添加內容
    [[NSRunLoop currentRunLoop] run];// 開啟RunLoop,默認是出于Default模式。
    NSLog(@"-------------run end -----------");// 正面run方法一直沒有結束
    
}@end

? 2.給Runloop中添加定時器也可以保證RunLoop直接退出。

- (void)viewDidLoad {[super viewDidLoad];// 創建自己的線程,并讓其執行run方法ZZThread *thread = [[ZZThread alloc] initWithTarget:self selector:@selector(test2) object:nil];self.testThread = thread;[self.testThread start];}- (void)test2{NSTimer *timer = [NSTimer timerWithTimeInterval:2 target:self selector:@selector(test) userInfo:nil repeats:YES];[[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode ];[[NSRunLoop currentRunLoop] run];}
- (void)test{NSLog(@"%s ------- %@",__func__,[NSThread currentThread]);
}

二:自動釋放池

? 1.RunLoop的自動釋放池的生命周期

??

? RunLoop在開始步驟1時會創建自動釋放池,并將之后的需要創建的臨時對象都放在池子里,然后在步驟6的時候會將池子銷毀,也就是對所有對象做一次realease操作。

也就是說RunLoop每跑一圈,到休眠這個周期里,自動釋放池的生命周期同時也是從創建到銷毀。

? 2016-1-24補充:

? ? Runloop內部是通過注冊一個Observer監聽RunLoop的狀態,當監聽到RunLoop的狀態為before waiting時,就會釋放自動釋放池。(kCFRunLoopBeforeWaiting)?

? ? 需要注意的是,Observer也會在這個時候在執行完銷毀自動釋放池的操作后,再創建一個自動釋放池,而不是在步驟1。?

? ?也就是說RunLoop中的自動釋放池都是在步驟6中銷毀與創建的!!!

? 2016 - 1- 24 16:00再次補充:

? ?可以打印出Runloop對象,發現它內部監聽自動釋放池的obserer對象的activities的值為1和160(32 + 128)

? ?也就是說observer對象其實監聽了Runloop的三個狀態:kCFRunLoopEntry,kCFRunLoopBeforeWaiting,kCFRunLoopExit

? ?kCFRunLoopEntry:Runloop的進入狀態,此時會第一次創建自動釋放池

? ?kCGRunLoopBeforeWaiting: RunLoop的休眠狀態前,此時會銷毀第一次在進入時創建的自動釋放池并又創建一個新的自動釋放池。

? ?kCFRunLoopExit: 直接銷毀自動釋放池

?

?

?

? 2.所以在創建RunLoop對象時應該也用一個自動釋放池包住

// 給線程添加一個RunLoop 讓線程"Live"
- (void)run
{@autoreleasepool {NSLog(@"%s -------------- %@",__func__,[NSThread currentThread]);// 如果RunLoop的Mode內沒有內容,RunLoop會被直接銷毀[[NSRunLoop currentRunLoop] addPort:[NSPort port] forMode:NSDefaultRunLoopMode];  // 給RunLoop的Mode里添加內容
        [[NSRunLoop currentRunLoop] run];// 開啟RunLoop,默認是出于Default模式。
        NSLog(@"-------------run end -----------");// 正面run方法一直沒有結束
        }}

?

轉載于:https://www.cnblogs.com/BJTUzhengli/p/5148992.html

總結

以上是生活随笔為你收集整理的2016 - 1- 21 - RunLoop使用(2016-1-24修改一次)(2016 - 1 - 24 再次修改)的全部內容,希望文章能夠幫你解決所遇到的問題。

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