ios同時スレッドの作成


同時スレッドの作成


メインスレッドはUIインタフェースやユーザインタラクションを扱うのが一般的である.他のことはダウンロード、計算など、別のスレッドで処理するのが一般的です...
まず、3つのスレッドを簡単に作成し、それぞれ1-1000を印刷し、便宜上、スレッド3をメインスレッドに置いて実行します.
- (void) firstCounter{ 
@autoreleasepool { 
NSUInteger counter = 0; 
for (counter = 0; 
counter < 1000; 
counter++){ 
NSLog(@"First Counter = %lu", (unsigned long)counter); 
} 
} 
} 
- (void) secondCounter{ 
@autoreleasepool { 
NSUInteger counter = 0; 

for (counter = 0; 
counter < 1000; 
counter++){ 
NSLog(@"Second Counter = %lu", (unsigned long)counter); 
} 
} 
} 
- (void) thirdCounter{ 
NSUInteger counter = 0; 
for (counter = 0; 
counter < 1000; 
counter++){ 
NSLog(@"Third Counter = %lu", (unsigned long)counter); 
} 
} 
- (void)viewDidLoad { 
[super viewDidLoad]; 
[NSThread detachNewThreadSelector:@selector(firstCounter) 
toTarget:self 
withObject:nil]; 
[NSThread detachNewThreadSelector:@selector(secondCounter) 
toTarget:self 
withObject:nil]; 
/* Run this on the main thread */ 
[self thirdCounter]; 
} 

thirdCounter関数は個々のスレッドで実行されないため、自動リリースプール(autorelease pool)は必要ありません.この方法はアプリケーションのメインスレッドで実行され、各Cocoa Touchプログラムは自動的にメインスレッドに自動リリースプールを作成します.コードの最後にdetachNewThreadSelectorを呼び出すことで、1番目のカウンタと2番目のカウンタを独立したスレッドで実行します.プログラムを実行すると、コンソールウィンドウに次の情報が表示されます.Second Counter=921 Third Counter=301 Second Counter=922 Second Counter=923 Second Counter=924 First Counter=956 Second Counter=925 Counter=957 Second Counter=926 First Counter=958 Third Counter=302 Second Counter=927 Third Counter=303 Second Counter=928
この3つのタイマは同時に動作し,出力された内容はランダムに交互に行われていることがわかる.各スレッドはautorelease poolを作成する必要があります.autorelease poolがreleaseされるまで、autorelease poolはautoreleasedされたオブジェクトの参照を保持します.参照カウントメモリ管理環境では、Cocoa Touchのオブジェクトがautoreleasedされるなど、非常に重要なメカニズムです.オブジェクトインスタンスが作成されると、オブジェクトの参照カウントは1になりますが、作成されたautorelease poolオブジェクトがreleaseされると、autoreleaseのオブジェクトもreleaseメッセージを送信します.この場合、その参照カウントが1の場合、オブジェクトは破棄されます.各スレッドは、スレッドが最初に作成されたオブジェクトとしてautorelease poolを作成する必要があります.そうしないと、そうしないと、スレッドが終了すると、スレッドに割り当てられたオブジェクトにメモリが漏洩します.よりよく理解するために、次のコードを見てみましょう.
- (void) autoreleaseThread:(id)paramSender{ 
NSBundle *mainBundle = [NSBundle mainBundle]; 
NSString *filePath = [mainBundle pathForResource:@"AnImage" 
ofType:@"png"]; 
UIImage *image = [UIImage imageWithContentsOfFile:filePath]; 
/* Do something with the image */ 
NSLog(@"Image = %@", image); 
} 
- (void)viewDidLoad { 
[super viewDidLoad]; 
[NSThread detachNewThreadSelector:@selector(autoreleaseThread:) 
toTarget:self 
withObject:self]; 
} 

このコードを実行すると、コンソールウィンドウにこのような出力情報が表示されます.
*** __NSAutoreleaseNoPool(): Object 0x5b2c990 of class NSCFString autoreleased with no pool in place - just leaking *** __NSAutoreleaseNoPool(): Object 0x5b2ca30 of class NSPathStore2 autoreleased with no pool in place - just leaking *** __NSAutoreleaseNoPool(): Object 0x5b205c0 of class NSPathStore2 autoreleased with no pool in place - just leaking *** __NSAutoreleaseNoPool(): Object 0x5b2d650 of class UIImage autoreleased with no pool in place - just leaking
上記の情報は、作成したautoreleaseのUIImageインスタンスがメモリ漏洩を生成し、FilePathや他のオブジェクトも漏洩を生成したことを示しています.これは、私たちのスレッドでは、開始時にautorelease poolを作成および初期化していないためです.次は正しいコードです.メモリの漏洩がないことを確認するためにテストしてください.
- (void) autoreleaseThread:(id)paramSender{ 
@autoreleasepool { 
NSBundle *mainBundle = [NSBundle mainBundle]; 
NSString *filePath = [mainBundle pathForResource:@"AnImage" 
ofType:@"png"]; 
UIImage *image = [UIImage imageWithContentsOfFile:filePath]; 
/* Do something with the image */ 
NSLog(@"Image = %@", image); 
} 
}