IOSマルチスレッド
4938 ワード
iOSマルチスレッド
iPhoneのスレッドアプリケーションは無節制ではなく、公式に提供された資料によると、iPhone OSの下のメインスレッドのスタックサイズは1 Mで、2番目のスレッドは512 KBだった.この値は、コンパイラスイッチまたはスレッドAPI関数では変更できません.
メインスレッドのみがUIを直接修正する能力があります.
一、NSOperationとNSOperationQueue
1、NSOperationから継承された操作クラスであって、このクラスの実装には-(void)mainメソッドが必要である.
2、NSOperationを使う最も簡単な方法は、NSOperationQueueに入れることです.
1つのオペレーションがキューに追加されると、キューは起動され、処理が開始されます(すなわち、オペレーションクラスのmainメソッドが呼び出されます).操作が完了すると、キューは解放されます.
self . queue = [[ NSOperationQueue alloc ] init ];
ArticleParseOperation *parser = [[ ArticleParseOperation alloc ] initWithData :filePath delegate : self ];
[queue addOperation :parser];
[parser release ];
[queue release];
3、操作キューに最も多くの同僚が実行する操作数を設定することができる:[queue setMaxConcurrentOperationCount:2];
二、NSThread<回転>
一、スレッド作成と起動スレッド作成には主に二つの方法がある.- (id)init; // designated initializer
- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
もちろん、いわゆるconvenient methodを使用すると、スレッドを直接生成して起動することができ、スレッドのクリーンアップに責任を負う必要はありません.このメソッドのインタフェースは、次のとおりです.+ (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument
最初の2つの方法が作成された後、携帯電話を起動する必要があります.起動する方法は次のとおりです.- (void)start;
二、スレッドの同期とロックはスレッドの同期とロックを説明し、最良の例は複数の窓口で同時に切符を販売する切符販売システムである可能性がある.Javaではsynchronizedを使用して同期することが知られていますが、iphoneではjavaの下のsynchronizedのようなキーワードは提供されていませんが、NSConditionオブジェクトインタフェースが提供されています.NSConditionのインタフェースの説明を見ると、NSConditionはiphoneの下のロックオブジェクトであるため、NSConditionを使用してiphoneのスレッドセキュリティを実現することができます.これはネット上の例ですhファイル// SellTicketsAppDelegate.h
import <UIKit/UIKit.h>
@interface SellTicketsAppDelegate : NSObject <UIApplicationDelegate> {
int tickets;
int count;
NSThread* ticketsThreadone;
NSThread* ticketsThreadtwo;
NSCondition* ticketsCondition;
UIWindow *window;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@end
SellTicketsAppDelegate.mファイル// SellTicketsAppDelegate.m
import "SellTicketsAppDelegate.h"
@implementation SellTicketsAppDelegate
@synthesize window;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
tickets = 100;
count = 0;
//
ticketCondition = [[NSCondition alloc] init];
ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[ticketsThreadone setName:@"Thread-1"];
[ticketsThreadone start];
ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[ticketsThreadtwo setName:@"Thread-2"];
[ticketsThreadtwo start];
//[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
// Override point for customization after application launch
[window makeKeyAndVisible];
}
- (void)run{
while (TRUE) {
//
[ticketsCondition lock];
if(tickets > 0){
[NSThread sleepForTimeInterval:0.5];
count = 100 - tickets;
NSLog(@" :%d, :%d, :%@",tickets,count,[[NSThread currentThread] name]);
tickets--;
}else{
break;
}
[ticketsCondition unlock];
}
}
- (void)dealloc {
[ticketsThreadone release];
[ticketsThreadtwo release];
[ticketsCondition release];
[window release];
[super dealloc];
}
@end
三、スレッドのインタラクティブスレッドは実行中に、メインスレッドでインタフェースを変更するなど、他のスレッドと通信する必要がある場合があります.以下のインタフェースを使用できます.- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
このプロセスでは、いくつかのリソースを解放する必要がある場合があります.次のように、NSAutoreleasePoolを使用して管理する必要があります.- (void)startTheBackgroundJob {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// to do something in your thread job
...
[self performSelectorOnMainThread:@selector(makeMyProgressBarMoving) withObject:nil waitUntilDone:NO];
[pool release];
}
何も考えずにスレッド関数内でautoreleaseを呼び出すと、NSAutoReleaseNoPool(): Object 0x********* of class NSConreteData autoreleased with no pool in place ….
というエラーが発生します.
四、スレッドプールについては、NSOperationに関する資料を見ることができます.
原帖:http://www.voland.com.cn/iphone-in-the-multi-threaded-programming
self . queue = [[ NSOperationQueue alloc ] init ];
ArticleParseOperation *parser = [[ ArticleParseOperation alloc ] initWithData :filePath delegate : self ];
[queue addOperation :parser];
[parser release ];
[queue release];
[queue setMaxConcurrentOperationCount:2];
- (id)init; // designated initializer
- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
+ (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument
- (void)start;
// SellTicketsAppDelegate.h
import <UIKit/UIKit.h>
@interface SellTicketsAppDelegate : NSObject <UIApplicationDelegate> {
int tickets;
int count;
NSThread* ticketsThreadone;
NSThread* ticketsThreadtwo;
NSCondition* ticketsCondition;
UIWindow *window;
}
@property (nonatomic, retain) IBOutlet UIWindow *window;
@end
// SellTicketsAppDelegate.m
import "SellTicketsAppDelegate.h"
@implementation SellTicketsAppDelegate
@synthesize window;
- (void)applicationDidFinishLaunching:(UIApplication *)application {
tickets = 100;
count = 0;
//
ticketCondition = [[NSCondition alloc] init];
ticketsThreadone = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[ticketsThreadone setName:@"Thread-1"];
[ticketsThreadone start];
ticketsThreadtwo = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
[ticketsThreadtwo setName:@"Thread-2"];
[ticketsThreadtwo start];
//[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
// Override point for customization after application launch
[window makeKeyAndVisible];
}
- (void)run{
while (TRUE) {
//
[ticketsCondition lock];
if(tickets > 0){
[NSThread sleepForTimeInterval:0.5];
count = 100 - tickets;
NSLog(@" :%d, :%d, :%@",tickets,count,[[NSThread currentThread] name]);
tickets--;
}else{
break;
}
[ticketsCondition unlock];
}
}
- (void)dealloc {
[ticketsThreadone release];
[ticketsThreadtwo release];
[ticketsCondition release];
[window release];
[super dealloc];
}
@end
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait
- (void)startTheBackgroundJob {
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
// to do something in your thread job
...
[self performSelectorOnMainThread:@selector(makeMyProgressBarMoving) withObject:nil waitUntilDone:NO];
[pool release];
}