前回「RunLoop学習ノート」で問題があった修復について
2306 ワード
前回の質問では、「常駐スレッド」を実現するためのシナリオ
前編「RunLoop学習ノート」では、常駐スレッドと、その実現方法について説明しています.
すなわち、サブスレッドを「消滅しない」状態にし、バックグラウンドでいくつかの頻発イベントを処理/他のスレッドからのメッセージの送信を待つは、サブスレッドにおいてネットワーク状態 を監視する.サブスレッドでタイマ をオンにする.サブスレッドで他の動作を長期にわたって監視する
AFNetworkingソースコードから抜粋すると、AFNはサブスレッドの下でRunLoopをデフォルトで開かず、手動で開く必要があるが、RunLoopが絶えず走るには以下の条件の1つを満たす必要がある. RunLoopには、ポートベースのイベントソース/customイベントソースなど を含むイベントソース(送信元)がある. RunLoop存在タイマ そのため、AFNがRunLoopのdefaultモードにNSMachPortポート(実際には他のポートでも可能)を追加したのは、RunLoopにイベントソースを追加したことに相当するため、RunLoopは絶えず走ることができ、スレッドの不死状態を保証するちなみに、AFNが常駐スレッドを維持している理由は、第一に、サブスレッドがデフォルトでRunLoopを開かないため、それは1つのC言語プログラムのようにすべてのコードを実行した後にスレッドを脱退することができて、ネットワーク要求は非同期で、これはネットワーク要求を通じてデータを取得した後に、スレッドはすでに脱退して、要求の成功/失敗の代理方法を実行することができなくて、そのためAFNは1つのRunLoopを開いて、スレッドを生存しました
メモリ漏洩の問題がある
研究bestswifterの文章を通じてRunloopとスレッドの生存に関する思想と結論を深く研究し,以前提案した案を改善し,著者に感謝した.
ソリューションは次のとおりです.
RunLoopスレッドの保存技術のより深い理解については、bestswifterの文章に移動してRunloopとスレッドの保存を深く研究してください.
前編「RunLoop学習ノート」では、常駐スレッドと、その実現方法について説明しています.
すなわち、サブスレッドを「消滅しない」状態にし、バックグラウンドでいくつかの頻発イベントを処理/他のスレッドからのメッセージの送信を待つ
+ (void)networkRequestThreadEntryPoint:(id)__unused object {
@autoreleasepool {
[[NSThread currentThread] setName:@"AFNetworking"];
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
[runLoop addPort:[NSMachPort port] forMode:NSDefaultRunLoopMode]; [runLoop run];
}
}
AFNetworkingソースコードから抜粋すると、AFNはサブスレッドの下でRunLoopをデフォルトで開かず、手動で開く必要があるが、RunLoopが絶えず走るには以下の条件の1つを満たす必要がある.
メモリ漏洩の問題がある
研究bestswifterの文章を通じてRunloopとスレッドの生存に関する思想と結論を深く研究し,以前提案した案を改善し,著者に感謝した.
ソリューションは次のとおりです.
- (void)memoryTest {
for (int i = 0; i < 100000; ++i) {
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[thread start];
[self performSelector:@selector(stopThread) onThread:thread withObject:nil waitUntilDone:YES];
}
}
- (void)stopThread {
CFRunLoopStop(CFRunLoopGetCurrent());
NSThread *thread = [NSThread currentThread];
[thread cancel];
}
- (void)run {
@autoreleasepool {
NSLog(@"current thread = %@", [NSThread currentThread]);
NSRunLoop *runLoop = [NSRunLoop currentRunLoop];
if (!self.emptyPort) {
self.emptyPort = [NSMachPort port];
}
[runLoop addPort:self.emptyPort forMode:NSDefaultRunLoopMode];
[runLoop runMode:NSRunLoopCommonModes beforeDate:[NSDate distantFuture]];
}
}
/bestswifter( )
:http://www.jianshu.com/p/10121d699c32
, , “ ”。
RunLoopスレッドの保存技術のより深い理解については、bestswifterの文章に移動してRunloopとスレッドの保存を深く研究してください.