IOS_다 중 루틴NSThread+NSOperation+GCD(Grand Central Dispatcher)

H:/0729/01_대상 방법 생 성 NSThread + 잠 금 + 티켓 팅ViewController.h
//  ViewController.h
//    
//  Created by apple on 13-7-29.
//  Copyright (c) 2013  itcast. All rights reserved.
#import <UIKit/UIKit.h>
@interface ViewController : UIViewController
//        
@property (weak, nonatomic) IBOutlet UITextView *infoTextView;
//       ,NSThread  
- (IBAction)threadSales:(id)sender;
@end

H:/0729/01_대상 방법 생 성 NSThread + 잠 금 + 티켓 팅ViewController.m
//  ViewController.m
//    
//  Created by apple on 13-7-29.
//  Copyright (c) 2013  itcast. All rights reserved.
#import "ViewController.h"
@interface ViewController ()
{
    NSInteger   _tickets;
    //         ,              
    NSLock      *_lock;
}
@end
@implementation ViewController
//    TextView      ,    ,          。
// 1.           
// 2.                     
// 3.         
//       UI   
- (void)appendTextView:(NSString *)text
{
	//   UI       
    NSMutableString *str = [NSMutableString stringWithString:_infoTextView.text];
	//       
    [str appendFormat:@"
%@", text]; NSLog(@"after append, text %@", str); // UI [_infoTextView setText:str]; // // , NSRange // NSRange NSRange range = NSMakeRange(str.length, 1); [_infoTextView scrollRangeToVisible:range]; } #pragma mark - NSThread // NSThread , - (void)threadSaleMethod { // 1. // 2. , // 3. -1 // 4. // : threadSaleMethod , !!! // : , : , , // 。 // : // 1. , if (_lock == nil) { _lock = [[NSLock alloc]init]; } // , , // 2. , // 3. , // while , ! while (YES) { // , >0, UI, --, [_lock lock]; if (_tickets > 0) { NSString *str = [NSString stringWithFormat:@" %d, %@", _tickets, [[NSThread currentThread]name]]; // UI // withObject ,waitUntilDone : [self performSelectorOnMainThread:@selector(appendTextView:) withObject:str waitUntilDone:YES]; _tickets--; // , , , [_lock unlock]; // if ([[[NSThread currentThread]name] isEqualToString:@" -1"]) { [NSThread sleepForTimeInterval:0.2]; } else { [NSThread sleepForTimeInterval:1.0]; } } else { // NSString *str = [NSString stringWithFormat:@" %@", [[NSThread currentThread]name]]; [self performSelectorOnMainThread:@selector(appendTextView:) withObject:str waitUntilDone:YES]; NSLog(@"%@", str); // break; } } } // ,NSThread , - (IBAction)threadSales:(id)sender { // 1. _tickets = 20; // 2. , // // [self threadSaleMethod]; // 1, NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(threadSaleMethod) object:nil]; // , [thread1 setName:@" 1"]; // [thread1 start]; // 2, NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(threadSaleMethod) object:nil]; // , [thread2 setName:@" 2"]; // NSThread , start, [thread2 start]; } @end

H:/0729/02_스 레 드 + NSOperation + Grand Central Dispatcher + 티켓 팅ViewController.h
//
//  ViewController.h
//    
//
//  Created by apple on 13-7-29.
//  Copyright (c) 2013  itcast. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

//        
@property (weak, nonatomic) IBOutlet UITextView *infoTextView;

// NSThread  
- (IBAction)threadSales:(id)sender;

// NSInvocationOperation  
- (IBAction)invocationSales:(id)sender;

// NSBlockOperation  
- (IBAction)blockSales:(id)sender;

// GCD  
- (IBAction)gcdSales:(id)sender;

@end

H:/0729/02_스 레 드 + NSOperation + Grand Central Dispatcher + 티켓 팅ViewController.m
</pre><pre name="code" class="objc">//  ViewController.m
//    
//  Created by apple on 13-7-29.
//  Copyright (c) 2013  itcast. All rights reserved.
#import "ViewController.h"
@interface ViewController ()
{
    NSInteger   _tickets;
    //    ,              
    NSLock      *_lock;
}
@end
@implementation ViewController
//    TextView      ,    ,          。
// 1.           
// 2.                     
// 3.         
//          
- (void)appendTextView:(NSString *)text
{
    NSMutableString *str = [NSMutableString stringWithString:_infoTextView.text];
    [str appendFormat:@"
%@", text]; // NSLog(@"append text %@", str); [_infoTextView setText:str]; // // , NSRange // NSRange NSRange range = NSMakeRange(str.length, 1); [_infoTextView scrollRangeToVisible:range]; } #pragma mark - NSThread // NSThread , - (void)threadSaleMethod { // 1. // 2. , // 3. -1 // 4. // : threadSaleMethod , !!! // : , : , , // 。 // : // 1. , if (_lock == nil) { _lock = [[NSLock alloc]init]; } // // NSLock *lock = [[NSLock alloc]init]; // 2. , // 3. , // while , ! while (YES) { // [_lock lock]; if (_tickets > 0) { // , NSString *str = [NSString stringWithFormat:@" %d, %@", _tickets, [[NSThread currentThread]name]]; // // // [self appendTextView:@"12"]; // waitUntilDone : [self performSelectorOnMainThread:@selector(appendTextView:) withObject:str waitUntilDone:YES]; _tickets--; // , [_lock unlock]; // ?? ? if ([[[NSThread currentThread]name] isEqualToString:@" -1"]) { [NSThread sleepForTimeInterval:0.2]; } else { [NSThread sleepForTimeInterval:0.3]; } } else { // [_lock unlock]; // // , NSString *str = [NSString stringWithFormat:@" %@", [[NSThread currentThread]name]]; [self performSelectorOnMainThread:@selector(appendTextView:) withObject:str waitUntilDone:YES]; NSLog(@"%@", str); // break; } } } // NSThread , - (IBAction)threadSales:(id)sender { // 1. _tickets = 100; // 2. , // // [self threadSaleMethod]; // 1 NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(threadSaleMethod) object:nil]; // [thread1 setName:@" -1"]; // [thread1 start]; // 2 NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(threadSaleMethod) object:nil]; [thread2 setName:@" -2"]; // NSThread , start, [thread2 start]; } #pragma mark - NSOperation , , UI // NSOperation , - (void)operationSaleMethod:(NSString *)operationName { // —— , !!! // 1. // 2. // 3. -1 // 4. while (YES) { // if (_tickets > 0) { [[NSOperationQueue mainQueue]addOperationWithBlock:^{ NSString *str = [NSString stringWithFormat:@" :%d, :%@", _tickets, operationName]; // UI [self appendTextView:str]; // _tickets--; }]; #warning if ([operationName isEqualToString:@"Operation - 1"] || [operationName isEqualToString:@"Block - 1"]) { [NSThread sleepForTimeInterval:0.2]; } else { [NSThread sleepForTimeInterval:1.0]; } } else { [[NSOperationQueue mainQueue]addOperationWithBlock:^{ NSString *str = [NSString stringWithFormat:@" , :%@", operationName]; // UI [self appendTextView:str]; }]; break; } } } //NSInvocationOperation , UI - (IBAction)invocationSales:(id)sender { _tickets = 20; // 1. // 1.1. ,NSThread // 1.2. id , , 。 NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operationSaleMethod:) object:@"Operation - 1"]; NSInvocationOperation *operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operationSaleMethod:) object:@"Operation - 2"]; // ? // 2. NSOperationQueue *queue = [[NSOperationQueue alloc]init]; // 3. , [queue addOperation:operation1]; [queue addOperation:operation2]; } // NSOperationQueue with Block , UI - (IBAction)blockSales:(id)sender { _tickets = 20; NSOperationQueue *queue = [[NSOperationQueue alloc]init]; [queue addOperationWithBlock:^{ [self operationSaleMethod:@"Block - 1"]; }]; [queue addOperationWithBlock:^{ [self operationSaleMethod:@"Block - 2"]; }]; [queue addOperationWithBlock:^{ [self operationSaleMethod:@"Block - 3"]; }]; [queue setMaxConcurrentOperationCount:2]; } #pragma mark - GCD // - (void)gcdSaleMethod:(NSString *)gcdName { // 1. // 2. // 3. -1 // 4. while (YES) { if (_tickets > 0) { // 1. // 2. , dispatch_async(dispatch_get_main_queue(), ^{ NSString *str = [NSString stringWithFormat:@" :%d, :%@", _tickets, gcdName]; [self appendTextView:str]; _tickets--; }); // if ([gcdName isEqualToString:@"GCD-1"]) { [NSThread sleepForTimeInterval:0.2]; } else { [NSThread sleepForTimeInterval:1.0]; } } else { // , , , break; } } } - (IBAction)gcdSales:(id)sender { _tickets = 20; // 1. // 0 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 2. dispatch_group_t group = dispatch_group_create(); // 3. , // , , , 。 dispatch_group_async(group, queue, ^{ [self gcdSaleMethod:@"GCD-1"]; }); dispatch_group_async(group, queue, ^{ [self gcdSaleMethod:@"GCD-2"]; }); // 4. , 2 UI, , dispatch_group_notify(group, dispatch_get_main_queue(), ^{ // !—— UI [self appendTextView:@" !"]; }); } @end

H:/0729/03_클래스 방법 생 성 NSThread + 그림 다운로드ViewController.h
//
//  ViewController.h
//         
//
//  Created by apple on 13-7-29.
//  Copyright (c) 2013  itcast. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

//       
@property (strong, nonatomic) IBOutletCollection(UIImageView) NSArray *imageViews;

// NSThread    
- (IBAction)threadDownload:(id)sender;

@end

H:/0729/03_클래스 방법 생 성 NSThread + 그림 다운로드ViewController.m
//  ViewController.m
//         
//  Created by apple on 13-7-29.
//  Copyright (c) 2013  itcast. All rights reserved.
#import "ViewController.h"
@interface ViewController ()
{
    NSInteger _imageIndex;
}
@end
@implementation ViewController
//             ,        ,            ,       URL
- (NSURL *)imageURL
{
    //             ,        17   ,        17        URL
    //   URL   
    // 1.   String
    // 1.1     1~17     ,            
    NSInteger index = arc4random() % 17 + 1;
    NSString *string = [NSString stringWithFormat:@"http://teacher.local/~apple/itcast/images/nat/NatGeo%02d.png", index];
    // 2. URLWithString
    return [NSURL URLWithString:string];
}
#pragma mark - NSThread    
//         
- (void)updateImages:(UIImage *)image
{
    //                      
    //      ,       ,       
    //          
    //                      
    //         ++,      4
    //     4?      
    //     ,           ,          
    _imageIndex = _imageIndex % 4;
    UIImageView *imageView = _imageViews[_imageIndex];
    [imageView setImage:image];
    _imageIndex++;
}
//       URL,  URL     
- (void)threadDownloadImage:(NSURL *)imageURL
{
    // 1.    URL   NSData;
    // 2.  NSData    ;
    //               ,  ,                  
    NSData *data = [NSData dataWithContentsOfURL:imageURL];
    UIImage *image = [UIImage imageWithData:data];
    //               
    // 1. UI    ,             
    //     ,           
    //       ,  image     ,         
    if (image != nil) {
        [self performSelectorOnMainThread:@selector(updateImages:)
									withObject:image waitUntilDone:YES];
    }
}
- (IBAction)threadDownload:(id)sender
{
    // 1.     
    // 1.1.     
    // 1.2.     
    // 2.     
    //          ,        
    //           ,    ,        object
    //      4       ,         
    for (NSInteger i = 0; i < 4; i++) {
        [NSThread detachNewThreadSelector:@selector(threadDownloadImage:)
								toTarget:self withObject:[self imageURL]];
    }
}
@end

H:/0729/04_다 중 루틴ViewController.h
//
//  ViewController.h
//  Tickets
//
//  Created by liufan on 13-7-27.
//  Copyright (c) 2013  itcast. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

//       
@property (weak, nonatomic) IBOutlet UITextView *infoTextView;

// NSThread  
- (IBAction)threadSales:(id)sender;
// NSBlockOperation  
- (IBAction)operationSales:(id)sender;
// NSInvocationOperation  
- (IBAction)invocationSales:(id)sender;
// GCD  
- (IBAction)gcdSales:(id)sender;

@end

H:/0729/04_다 중 루틴ViewController.m
//
//  ViewController.m
//  Tickets
//
//  Created by liufan on 13-7-27.
//  Copyright (c) 2013  itcast. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
{
    //     ,    
    int     _tickets;
    //    ,NSThread  
    NSLock  *_threadLock;
}

@end

@implementation ViewController

//         
- (void)appendTextView:(NSString *)text
{
    NSMutableString *str = [NSMutableString stringWithString:[_infoTextView text]];
    [str appendFormat:@"
%@", text]; NSRange range = NSMakeRange(str.length, 1); [_infoTextView setText:str]; // [_infoTextView scrollRangeToVisible:range]; } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } #pragma mark - NSThread // NSThread - (void)threadSaleMethod { // , if (_threadLock == nil) { _threadLock = [[NSLock alloc]init]; } // 1. > 0 // 1.1. // 1.2. // 1.3. // 2. while (YES) { // [_threadLock lock]; if (_tickets > 0) { NSString *str = [NSString stringWithFormat:@" :%d, :%@", _tickets, [[NSThread currentThread]name]]; // UI [self performSelectorOnMainThread:@selector(appendTextView:) withObject:str waitUntilDone:YES]; _tickets--; // [_threadLock unlock]; // if ([[[NSThread currentThread]name] isEqualToString:@" -1"]) { [NSThread sleepForTimeInterval:1.0f]; } else { [NSThread sleepForTimeInterval:0.1f]; } } else { // [_threadLock unlock]; NSString *str = [NSString stringWithFormat:@" , :%@", [[NSThread currentThread]name]]; // UI [self performSelectorOnMainThread:@selector(appendTextView:) withObject:str waitUntilDone:YES]; break; } } } // NSThread - (IBAction)threadSales:(id)sender { // , ! _tickets = 20; // 1 NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(threadSaleMethod) object:nil]; // , , [thread1 setName:@" -1"]; // 1 [thread1 start]; // 2, NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(threadSaleMethod) object:nil]; [thread2 setName:@" -2"]; [thread2 start]; } #pragma mark - NSOperation // NSOperation - (void)operationSaleMethod:(NSString *)operationName { while (YES) { if (_tickets > 0) { // [[NSOperationQueue mainQueue]addOperationWithBlock:^{ NSString *str = [NSString stringWithFormat:@" :%d, :%@", _tickets, operationName]; [self appendTextView:str]; _tickets--; }]; // if ([operationName isEqualToString:@" -1"]) { [NSThread sleepForTimeInterval:0.1f]; } else { [NSThread sleepForTimeInterval:0.2f]; } } else { // [[NSOperationQueue mainQueue]addOperationWithBlock:^{ NSString *str = [NSString stringWithFormat:@" , :%@", operationName]; [self appendTextView:str]; }]; break; } } } // NSBlockOperation - (IBAction)operationSales:(id)sender { // , ! _tickets = 20; // NSOperationQueue *queue = [[NSOperationQueue alloc]init]; [queue addOperationWithBlock:^{ [self operationSaleMethod:@" -1"]; }]; [queue addOperationWithBlock:^{ [self operationSaleMethod:@" -2"]; }]; [queue addOperationWithBlock:^{ [self operationSaleMethod:@" -3"]; }]; // [queue setMaxConcurrentOperationCount:2]; } // NSInvocationOperation - (IBAction)invocationSales:(id)sender { // , ! _tickets = 20; // 1 NSInvocationOperation *operation1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operationSaleMethod:) object:@" -1"]; // 2 NSInvocationOperation *operation2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(operationSaleMethod:) object:@" -2"]; // NSOperationQueue *queue = [[NSOperationQueue alloc]init]; [queue addOperation:operation1]; [queue addOperation:operation2]; } #pragma mark - GCD // GCD - (void)gcdSaleMethod:(NSString *)gcdName { while (YES) { if (_tickets > 0) { // dispatch_async(dispatch_get_main_queue(), ^{ NSString *str = [NSString stringWithFormat:@" :%d, :%@", _tickets, gcdName]; [self appendTextView:str]; _tickets--; }); // if ([gcdName isEqualToString:@" GCD-1"]) { [NSThread sleepForTimeInterval:0.1f]; } else { [NSThread sleepForTimeInterval:0.2f]; } } else { break; } } } // GCD - (IBAction)gcdSales:(id)sender { // , ! _tickets = 20; // 1. , , 0 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 2. dispatch_group_t group = dispatch_group_create(); // 3. dispatch_group_async(group, queue, ^{ [self gcdSaleMethod:@" GCD-1"]; }); dispatch_group_async(group, queue, ^{ [self gcdSaleMethod:@" GCD-2"]; }); // 4. dispatch_group_notify(group, dispatch_get_main_queue(), ^{ [self appendTextView:@" "]; }); } @end

H:/0729/05_다 중 루틴 다운로드 UIImageViewController.h
//
//  ViewController.h
//     UIImage  
//
//  Created by liufan on 13-7-29.
//  Copyright (c) 2013  itcast. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

//       
@property (strong, nonatomic) IBOutletCollection(UIImageView) NSArray *imageViews;

// NSThread    
- (IBAction)threadDownload:(id)sender;
// NSOperation    
- (IBAction)operationDownload:(id)sender;
// GCD    
- (IBAction)gcdDownload:(id)sender;

@end

H:/0729/05_다 중 루틴 다운로드 UIImageViewController.m
//
//  ViewController.m
//     UIImage  
//
//  Created by liufan on 13-7-29.
//  Copyright (c) 2013  itcast. All rights reserved.
//

#import "ViewController.h"

@interface ViewController ()
{
    //     
    NSInteger       _imageIndex;
}

@end

@implementation ViewController

//      URL,   17   
- (NSURL *)imageURL
{
    NSInteger index = (arc4random() % 17) + 1;
    NSString *urlString = [NSString stringWithFormat:@"http://localhost/~liufan9/itcast/images/nat/NatGeo%02d.png", index];
    
    return [NSURL URLWithString:urlString];
}

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

//       
- (void)updateImageViews:(UIImage *)image
{
    if (_imageIndex > 3) {
        _imageIndex = _imageIndex % 4;
    }
    
    UIImageView *imageView = _imageViews[_imageIndex];
    [imageView setImage:image];
    
    _imageIndex++;
}

#pragma mark - NSThread    
- (void)threadDownloadMethod:(NSURL *)imageURL
{
    // 1.     URL    
    // 2.             
    NSData *data = [NSData dataWithContentsOfURL:imageURL];
    UIImage *image = [UIImage imageWithData:data];
    
    if (image != nil) {
        //   UI
        [self performSelectorOnMainThread:@selector(updateImageViews:) withObject:image waitUntilDone:YES];
    }
}

- (IBAction)threadDownload:(id)sender
{
    // 1.         ,    URL   
    // 2.     
    // 3.     
    // 4.           
    
    //       
    for (NSInteger i = 0; i < 4; i++) {
        [NSThread detachNewThreadSelector:@selector(threadDownloadMethod:) toTarget:self withObject:[self imageURL]];
    }
}

#pragma mark - NSOperation    
- (void)operationDownloadImage:(NSURL *)imageURL
{
    // 1.     URL    
    // 2.             
    NSData *data = [NSData dataWithContentsOfURL:imageURL];
    UIImage *image = [UIImage imageWithData:data];
    
    if (image != nil) {
        //   UI
        [[NSOperationQueue mainQueue]addOperationWithBlock:^{
            [self updateImageViews:image];
        }];
    }
}

- (IBAction)operationDownload:(id)sender
{
    // 1.       ,    URL   
    // 2.     
    // 3.         
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    
    for (NSInteger i = 0; i < 4; i++) {
        [queue addOperationWithBlock:^{
            [self operationDownloadImage:[self imageURL]];
        }];
    }
}

#pragma mark - GCD    
- (void)gcdDownloadImage:(NSURL *)imageURL
{
    // 1.     URL    
    // 2.             
    NSData *data = [NSData dataWithContentsOfURL:imageURL];
    UIImage *image = [UIImage imageWithData:data];
    
    if (image != nil) {
        //   UI
        dispatch_async(dispatch_get_main_queue(), ^{
            [self updateImageViews:image];
        });
    }
}

- (IBAction)gcdDownload:(id)sender
{
    // 1.   gcd    
    // 1.         
    // 2.       
    // 3.           
    // 4.             
    
    //   :           ,      dispatch_async  
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    for (NSInteger i = 0; i < 4; i++) {
        dispatch_async(queue, ^{
            [self gcdDownloadImage:[self imageURL]];
        });
    }
}
@end

H:/0729/06_다 중 루틴원자 속성 잠 금 자원ViewController.h
//
//  ViewController.h
//  Tickets
//
//  Created by liufan on 13-7-27.
//  Copyright (c) 2013  itcast. All rights reserved.
//

#import <UIKit/UIKit.h>

@interface ViewController : UIViewController

//       
@property (weak, nonatomic) IBOutlet UITextView *infoTextView;

// NSThread  
- (IBAction)threadSales:(id)sender;
// NSBlockOperation  
- (IBAction)operationSales:(id)sender;
// NSInvocationOperation  
- (IBAction)invocationSales:(id)sender;
// GCD  
- (IBAction)gcdSales:(id)sender;

@end

H:/0729/06_다 중 루틴원자 속성 잠 금 자원ViewController.m
//  ViewController.m
//  Tickets
//  Created by liufan on 13-7-27.
//  Copyright (c) 2013  itcast. All rights reserved.
#import "ViewController.h"
@interface ViewController ()
{
    //     ,    
//    int     _tickets;
    //    ,NSThread  
    NSLock  *_threadLock;
}
//  iOS ,           ,          “    ”
//       ,             。
@property (assign, atomic) int tickets;
@end
@implementation ViewController
//         
- (void)appendTextView:(NSString *)text
{
    NSMutableString *str = [NSMutableString stringWithString:[_infoTextView text]];
    [str appendFormat:@"
%@", text]; NSRange range = NSMakeRange(str.length, 1); [_infoTextView setText:str]; // [_infoTextView scrollRangeToVisible:range]; } #pragma mark - NSThread // NSThread - (void)threadSaleMethod { // , if (_threadLock == nil) { _threadLock = [[NSLock alloc]init]; } // 1. > 0 // 1.1. // 1.2. // 1.3. // 2. while (YES) { // [_threadLock lock]; /** : NSThread , , , 。 */ if (_tickets > 0) { // NSString *str = [NSString stringWithFormat:@" :%d, :%@", _tickets, [[NSThread currentThread]name]]; // UI [self performSelectorOnMainThread:@selector(appendTextView:) withObject:str waitUntilDone:YES]; _tickets--; // [_threadLock unlock]; } else { // [_threadLock unlock]; NSString *str = [NSString stringWithFormat:@" , :%@", [[NSThread currentThread]name]]; // UI [self performSelectorOnMainThread:@selector(appendTextView:) withObject:str waitUntilDone:YES]; break; } // if ([[[NSThread currentThread]name] isEqualToString:@" -1"]) { [NSThread sleepForTimeInterval:1.0f]; } else { [NSThread sleepForTimeInterval:0.1f]; } } } // NSThread - (IBAction)threadSales:(id)sender { // , ! _tickets = 20; // 1 NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(threadSaleMethod) object:nil]; // , , [thread1 setName:@" -1"]; // 1 [thread1 start]; // 2, NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(threadSaleMethod) object:nil]; [thread2 setName:@" -2"]; [thread2 start]; } #pragma mark - NSOperation // NSOperation - (void)operationSaleMethod:(NSString *)operationName { while (YES) { /** : 1. NSOperation , , ! 2. 。 */ @synchronized(self) { if (self.tickets > 0) { // , NSString *str = [NSString stringWithFormat:@" :%d, :%@", self.tickets, operationName]; [[NSOperationQueue mainQueue]addOperationWithBlock:^{ [self appendTextView:str]; }]; self.tickets--; } else { // [[NSOperationQueue mainQueue]addOperationWithBlock:^{ NSString *str = [NSString stringWithFormat:@" , :%@", operationName]; [self appendTextView:str]; }]; break; } } // , , if ([operationName isEqualToString:@" -1"]) { [NSThread sleepForTimeInterval:0.1f]; } else { [NSThread sleepForTimeInterval:0.5f]; } } } // NSBlockOperation - (IBAction)operationSales:(id)sender { /* , ! , , */ _tickets = 20; // NSOperationQueue *queue = [[NSOperationQueue alloc]init]; [queue addOperationWithBlock:^{ [self operationSaleMethod:@" -1"]; }]; [queue addOperationWithBlock:^{ [self operationSaleMethod:@" -2"]; }]; [queue addOperationWithBlock:^{ [self operationSaleMethod:@" -3"]; }]; // [queue setMaxConcurrentOperationCount:2]; } // NSInvocationOperation - (IBAction)invocationSales:(id)sender { // , ! _tickets = 20; // 1 NSInvocationOperation *operation1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationSaleMethod:) object:@" -1"]; // 2 NSInvocationOperation *operation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(operationSaleMethod:) object:@" -2"]; // NSOperationQueue *queue = [[NSOperationQueue alloc]init]; [queue addOperation:operation1]; [queue addOperation:operation2]; } #pragma mark - GCD // GCD - (void)gcdSaleMethod:(NSString *)gcdName { while (YES) { /** : 1. GCD , , ! 2. 。 */ @synchronized(self) { if (self.tickets > 0) { // UI , 。 NSString *str = [NSString stringWithFormat:@" :%d, :%@", self.tickets, gcdName]; dispatch_async(dispatch_get_main_queue(), ^{ [self appendTextView:str]; }); // self.tickets--; } else { break; } } // if ([gcdName isEqualToString:@" GCD-1"]) { [NSThread sleepForTimeInterval:0.1f]; } else { [NSThread sleepForTimeInterval:0.2f]; } } } // GCD - (IBAction)gcdSales:(id)sender { /* , ! , , */ _tickets = 20; // 1. , , 0 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 2. dispatch_group_t group = dispatch_group_create(); // 3. dispatch_group_async(group, queue, ^{ [self gcdSaleMethod:@" GCD-1"]; }); dispatch_group_async(group, queue, ^{ [self gcdSaleMethod:@" GCD-2"]; }); // 4. dispatch_group_notify(group, dispatch_get_main_queue(), ^{ [self appendTextView:@" "]; }); } @end

좋은 웹페이지 즐겨찾기