天天看點

IOS多線程之——NSThread

NSThread的使用

NSThread 有兩種直接建立方式:

- (id)initWithTarget:(id)target selector:(SEL)selector object:(id)argument

+ (void)detachNewThreadSelector:(SEL)aSelector toTarget:(id)aTarget withObject:(id)anArgument

第一個是執行個體方法,第二個是類方法

1、[NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:nil];  
2、NSThread* myThread = [[NSThread alloc] initWithTarget:self  
                                        selector:@selector(doSomething:)  
                                        object:nil];  
[myThread start];            

參數的意義:

selector :線程執行的方法,這個selector隻能有一個參數,而且不能有傳回值。

target  :selector消息發送的對象

argument:傳輸給target的唯一參數,也可以是nil

第一種方式會直接建立線程并且開始運作線程,第二種方式是先建立線程對象,然後再運作線程操作,在運作線程操作前可以設定線程的優先級等線程資訊

不顯式建立線程的方法:

用NSObject的類方法  performSelectorInBackground:withObject: 建立一個線程:

[Obj performSelectorInBackground:@selector(doSomething) withObject:nil];

下載下傳圖檔的例子:

初始化圖檔連結:

#define kURL @"http://avatar.csdn.net/2/C/D/1_totogo2010.jpg"            

初始化UIImageView:

self.imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.view.frame.size.width, self.view.frame.size.height)];
    [self.imageView setBackgroundColor:[UIColor redColor]];
    [self.view addSubview:self.imageView];
    
    [NSThread detachNewThreadSelector:@selector(downloadImage:) toTarget:self withObject:kURL];
           

更新ui:

-(void)downloadImage:(NSString *) url{
    NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]];
    UIImage *image = [[UIImage alloc]initWithData:data];
    if(image == nil)
    {
        
    }else
    {
        [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];
    }
}

-(void)updateUI:(UIImage*) image
{
    self.imageView.image = image;
}           

線程下載下傳完圖檔後怎麼通知主線程更新界面呢?

[self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES];

performSelectorOnMainThread是NSObject的方法,除了可以更新主線程的資料外,還可以更新其他線程的比如:

用:performSelector:onThread:withObject:waitUntilDone: 

線程同步

我們示範一個經典的賣票的例子來講NSThread的線程同步:

.h檔案:

@interface AppDelegate : UIResponder <UIApplicationDelegate>
{
    int tickets;
    int count;
    NSThread* ticketsThreadone;
    NSThread* ticketsThreadtwo;
    NSCondition* ticketsCondition;
    NSLock *theLock;
}
           

.m檔案:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
    // Override point for customization after application launch.
    
    tickets = 100;
    count = 0;
    theLock = [[NSLock alloc] init];
    // 鎖對象
    ticketsCondition = [[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];
    
    
    
    
    self.rootViewController = [[RootViewController alloc]init];
    [self.window setRootViewController:self.rootViewController];
    [self.window addSubview:self.rootViewController.view];
    
    
    
    self.window.backgroundColor = [UIColor whiteColor];
    [self.window makeKeyAndVisible];
    return YES;
}           
- (void)run
{
    while (TRUE)
    {
        // 上鎖
        //        [ticketsCondition lock];
        [theLock lock];
        if(tickets >= 0){
            [NSThread sleepForTimeInterval:0.09];
            count = 100 - tickets;
            NSLog(@"目前票數是:%d,售出:%d,線程名:%@",tickets,count,[[NSThread currentThread] name]);
            tickets--;
        }else{
            break;
        }
        [theLock unlock];
        //        [ticketsCondition unlock];
    }  
}
           

其他同步

我們可以使用指令 @synchronized 來簡化 NSLock的使用,這樣我們就不必顯示編寫建立NSLock,加鎖并解鎖相關代碼。

- (void)doSomeThing:(id)anObj

{

    @synchronized(anObj)

    {

        // Everything between the braces is protected by the @synchronized directive.

    }

}

還有其他的一些鎖對象,比如:循環鎖NSRecursiveLock,條件鎖NSConditionLock,分布式鎖NSDistributedLock等等,可以自己看官方文檔學習

著作權聲明:本文由http://blog.csdn.net/totogo2010/原創,歡迎轉載分享。請尊重作者勞動,轉載時保留該聲明和作者部落格連結,謝謝!