NSThread實現多執行緒

weixin_34146805發表於2016-04-06
  • 建立NSThread有三種方式
//1.建立一個新執行緒物件
-(instancetype)initWithTarget:(id)target selector:(SEL)sel object:(id)arg
//2.建立並啟動新執行緒
 +(void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument
 //3.隱式建立並啟動執行緒
 -()void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg

三種方法都是將target物件的selector方法轉換為執行緒執行體,selector最多接收一個引數,arg代表傳給selector方法的引數。

  • 舉個?:
 -(void)viewDidLoad {
    [super viewDidLoad];
    for (int i = 0; i < 100; i++) {
        NSLog(@"===%@===%d",[NSThread currentThread], i);
        if (i == 20) {
            //建立執行緒的物件
            NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
            //啟動執行緒
            [thread start];
            [NSThread sleepForTimeInterval:0.001];
            //建立並啟動新執行緒
            //[NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
        }
    }
}

-(void)run{
    for (int i = 0; i < 100; i++) {
        NSLog(@"-----%@------%d",[NSThread currentThread], i);
    }
}
  • +(NSThread *)currentThread:返回當前正在執行的執行緒物件。

  • 此程式建立了兩個執行緒,程式顯式的建立了一個子執行緒。當iOS應用執行後,至少建立一個主執行緒(UI執行緒)。

  • 程式建立執行緒後,該執行緒處於新建狀態,但是系統僅僅為其分配了記憶體,並初始化了成員變數的值。此時的執行緒物件沒有執行緒的動態特徵,程式也不會執行執行緒的執行體。在呼叫start方法後,該執行緒處於就緒狀態,何時執行取決於系統排程。

  • 執行緒的結束方式
    1.執行緒執行體方法執行完成,執行緒正常結束。
    2.執行緒執行過程中出現錯誤。
    3.呼叫NSThread類的exit方法終止當前正在執行的執行緒。

舉個?:

@implementation FKViewController
NSThread* thread;
- (void)viewDidLoad
{
    [super viewDidLoad];
    // 建立新執行緒物件
    thread = [[NSThread alloc] initWithTarget:self selector:@selector(run)
        object:nil];
    // 啟動新執行緒
    [thread start];
    
    //[self performSelectorInBackground:@selector(run) withObject:nil];
}
- (void)run
{
    for(int i = 0 ; i < 100 ; i++)
    {
        if([NSThread currentThread].isCancelled)
        {
            // 終止當前正在執行的執行緒
            [NSThread exit];
        }
        NSLog(@"-----%@----%d" , [NSThread currentThread].name, i);
        // 每執行一次,執行緒暫停0.5秒
        [NSThread sleepForTimeInterval:0.5];
    }
}
- (IBAction)cancelThread:(id)sender
{
    // 取消thread執行緒,呼叫該方法後,thread的isCancelled方法將會返回NO
    [thread cancel]; 
}
@end
  • thread物件呼叫cancel方法,向thread物件傳送取消訊號,這樣可以使thread物件的isCancelled方法返回YES。(線上程執行過程中isExecuting方法返回YES;執行緒執行完成後isFinished方法返回YES)

  • 執行緒物件呼叫exit方法終止執行緒。

  • +(void)sleepForTimeInterval:(NSTimeInterval)ti
    讓當前正在執行的執行緒暫停ti秒,進入阻塞狀態。

  • +(void)sleepUntilDate:(NSDate *)aDate
    讓當前正在執行的執行緒暫停到aDate代表的時間,並進入阻塞狀態。

  • 執行緒優先順序
    1.+threadPriority:該類方法獲取正在執行執行緒的優先順序。
    2.-threadPriority:該例項方法獲取呼叫該方法的執行緒物件的優先順序。
    3.+(BOOL)setThreadPriority:(double)priority:該類方法用於設定當前正在執行的執行緒的優先順序。
    4.-(BOOL)setThreadPriority:(double)priority:該例項方法用於設定當前正在執行的執行緒的優先順序。

注意:setThreadPriority:(double)priority方法的引數可以是一個double型別的浮點數,範圍為0.0~1.0,其中1.0等級最高,0.0等級最低。

  • 舉個?:
-(void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"UI執行緒的優先順序為:%g", [NSThread threadPriority]);
    //建立第一個執行緒物件
    NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
    //設定執行緒的名字
    thread1.name = @"執行緒A";
    NSLog(@"執行緒A的優先順序為:%g",thread1.threadPriority);
    //設定使用最低優先順序
    thread1.threadPriority = 0.0;
    NSThread *thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
    thread2.name = @"執行緒B";
    NSLog(@"執行緒A的優先順序為:%g",thread2.threadPriority);
    thread2.threadPriority = 1.0;
    [thread1 start];
    [thread2 start];
}
-(void)run{
    for (int i = 0; i < 100; i++) {
        NSLog(@"-----%@-----%d",[NSThread currentThread].name, i);
    }
}

相關文章