天天看點

用NSThread建立子線程

關于線程的原理和優缺點在這裡我就不寫了,因為我也實在弄不清楚。由于Mac OS是基于Unix的核心搭建的作業系統,是以基本的POSIX标準肯定是支援的,我們看官方手冊上也提到我們可以放心使用POSIX的線程程式設計。

除了POSIX一種選擇外,蘋果提供了NSThread類也可以實作多線程程式設計。使用NSThread建立線程有下面兩種方式

  • 使用detachNewThreadSelector:toTarget:withObject: 類的方法建立新線程
  • 建立一個新的NSThread執行個體,調用start方法(隻在iOS以及Max OS X10.5及以上版本)

第一種方法在Max OS中使用曆史比較悠久了,很多項目中都可以看到這樣的代碼。

#import <Foundation/Foundation.h>

@interface MyThread : NSObject
{
		
}

-(void)start:(int)times;
-(void)work:(NSNumber *)times;

@end

@implementation MyThread

//建立子線程
-(void)start:(int)times
{
	//建立方法一
	[NSThread detachNewThreadSelector:@selector(work:) toTarget:self withObject:[NSNumber numberWithInt:times]];
	
	//建立方法二
	/*	
	NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(work:) 
												 object:[NSNumber numberWithInt:times]];
	[thread start];
	 */
}

//子線程入口函數
-(void)work:(NSNumber *)times
{
	int i = 0;
	for(i = 0;i < [times intValue];i ++)
	{
		[NSThread sleepForTimeInterval:0.5];
		printf("child thread %d\n",i);
	}
}

@end

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
	//建立子線程工作的執行個體
	MyThread *mt = [[[MyThread alloc] init] autorelease];
	[mt start:5];
	
	//主線程代碼
	int i = 0;
	for(i = 0;i < 10;i ++)
	{
		[NSThread sleepForTimeInterval:0.5];
		printf("main thread %d\n",i);
	}
	
	[pool drain];
    return 0;
}
           

運作結果如下所示

main thread 0
child thread 0
main thread 1
child thread 1
child thread 2
main thread 2
main thread 3
child thread 3
child thread 4
main thread 4
main thread 5
main thread 6
main thread 7
main thread 8
main thread 9
           

此外還有一種建立方法,就是使用NSObject的performSelectorInBackground:withObject方法來建立線程,隻需要将上面main函數中建立子線程工作的執行個體部分替換為如下代碼即可。

//建立子線程工作的執行個體
	MyThread *mt = [[[MyThread alloc] init] autorelease];
	[mt performSelectorInBackground:@selector(work:) withObject:[NSNumber numberWithInt:5]];
           

當然如今流行的并發程式設計不再是多線程了,在windows,linux平台我們都了解到各種異步程式設計模型了,Mac OS系統中也提供了強大的NSOperationQueue,我們隻需要定義自己的工作内容,投遞給作業系統的線程池幫我們處理即可。代碼如下:

#import <Foundation/Foundation.h>

//類定義
@interface MyWork : NSOperation
{
    int times;
}

@property int times;

-(void)main;

@end

//類實作
@implementation MyWork

@synthesize times; 

-(void)main
{
    int i;
    
    for (i=0; i<times; i++) {
        [NSThread sleepForTimeInterval:0.5];
        NSLog(@"child operation running at %d",i);
    }
}

@end

int main (int argc, const char * argv[]) {
    NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
	
    //建立“線程池”
    NSOperationQueue *queue = [[NSOperationQueue alloc] init];
    
    MyWork *work = [[[MyWork alloc] init] autorelease];
    work.times = 5;
    
    //添加操作
    [queue addOperation:work];
    
    int i;
    for (i=0; i<10; i++) {
        [NSThread sleepForTimeInterval:0.5];
        NSLog(@"main operation running at %d",i);
    }
    
    [queue release];
	[pool drain];
    return 0;
}