IOS_다중 스레드표를 팔다

H:/1007/01_다중 스레드대퀘스트MainViewController.m
//  MainViewController.m
//     -01.   
//  Created by apple on 13-10-7.
#import "MainViewController.h"
@interface MainViewController ()
@property (weak, nonatomic) UIImageView *imageView;
@end
@implementation MainViewController
/*
 NSObject     
 
 1. [NSThread currentThread]            
    num = 1       
             (NSThread,NSOperation,GCD),
	        ,         。
 
 2.       ,    
    [self performSelectorInBackground:@selector(bigTask)
										withObject:nil]
 
      performSelectorInBackground     UI ,
	  ,         。
 
 3.     
      performSelectorOnMainThread           。
	           YES,   ,      
      :NSObject          。
 
 4.     
           @autoreleasepool(     ) ,
				          ,       。
 */
- (void)viewDidLoad
{
    [super viewDidLoad];
	//    1   ,         
    UIButton *btn1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [btn1 setFrame:CGRectMake(110, 100, 100, 40)];
    [btn1 setTitle:@"   " forState:UIControlStateNormal];
    [btn1 addTarget:self action:@selector(btnClick_1)
						  forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn1];
	//    2   ,         
    UIButton *btn2 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [btn2 setFrame:CGRectMake(110, 200, 100, 40)];
    [btn2 setTitle:@"   " forState:UIControlStateNormal];
    [btn2 addTarget:self action:@selector(btnClick_2) 
						  forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn2];
    NSLog(@"%@", [NSThread currentThread]);
	//           
    UIImageView *imageView = [[UIImageView alloc]initWithFrame:
										CGRectMake(110, 260, 100, 100)];
    UIImage *image = [UIImage imageNamed:@"  1.png"];
    [imageView setImage:image];
    [self.view addSubview:imageView];
    self.imageView = imageView;
}
//     1     
- (void)btnClick_1
{
    //          
    // performSelectorInBackground         ,
	//              
    [self performSelectorInBackground:@selector(btn_1_bigTask)
										withObject:nil];
    NSLog(@"     : %@", [NSThread currentThread]);
}
#pragma mark     
- (void)btn_1_bigTask
{
    @autoreleasepool {        
        for (NSInteger i = 0; i < 300; i++) {
            NSString *str = [NSString stringWithFormat:@"i = %i", i];
            NSLog(@"%@", str);
        }
        NSLog(@"    - %@", [NSThread currentThread]);
        UIImage *image = [UIImage imageNamed:@"  2.png"];
        //        self.imageView image
		//   self         ,         
        [self performSelectorOnMainThread:@selector(changeImage:) 
							  withObject:image waitUntilDone:YES];
		//     self.imageView   setImage:  ,     image
        [self.imageView performSelectorOnMainThread:@selector(setImage:)
									withObject:image waitUntilDone:YES];
    }
}
//      ,    
- (void)changeImage:(UIImage *)image
{
    NSLog(@"     %@", [NSThread currentThread]);
    [self.imageView setImage:image];
}

//     2   ,       
- (void)btnClick_2
{
    NSLog(@"     :%@", [NSThread currentThread]);
    [self btn_2_smallTask];
}
//      
- (void)btn_2_smallTask
{
    NSString *str = nil;
    for (NSInteger i = 0; i < 30000; i++) {
        str = [NSString stringWithFormat:@"i = %i", i];
    }
    NSLog(@"%@", str);
    NSLog(@"    - %@", [NSThread currentThread]);
}
@end

H:/1007/02_다중 스레드그림 로드MainViewController.m
//  MainViewController.m
//     -02.    
//  Created by apple on 13-10-7.
#import "MainViewController.h"
@interface MainViewController ()
//     
@property (strong, nonatomic) NSSet *imageViewSet;
//       ,NSOperationQueue
@property (strong, nonatomic) NSOperationQueue *operationQueue;
@end
@implementation MainViewController
/*
 1. NSThread
    1>     detachNewThreadSelector
              ,       
 
    2>      initWithTarget
            start  ,            
 
      :  
      :
        *              
        *        
		*       
        *       
          :    (    ) ->     (    ) ->   UI(   )
 
 2. NSOperation
    1> NSInvocationOperation
    2> NSBlockOperation
 
       Operation  ,      NSOperationQueue      ,    
 
      :
    1>  setMaxConcurrentOperationCount              
    2>  addDependency              ,
					                 ,    ,     
 
      :
       UI,    [NSOperationQueue mainQueue]addOperationWithBlock:
               
 
 3. GCD
     1)   global  ,     ,     ,       
       :dispatch_get_global_queue(      )
        :DISPATCH_QUEUE_PRIORITY_DEFAULT
            (  )   
     
     2)               ,       
       :dispatch_queue_create(      ,         )
       :        ,      @
     
     3)    
          
       :dispatch_get_main_queue(     )
 
     gcd ,                  ,        
 
        、            ,       ,  !
	
  4.    (         ,       ,     ,      )
		dispatch_queue_t queue = dispatch_get_global_queue(
						DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
		    (          )
		dispatch_queue_t queue = dispatch_queue_create("myQueue", 
										DISPATCH_QUEUE_SERIAL);
		   
		dispatch_get_main_queue();

	    
		dispatch_async                
		

	    
		dispatch_sync          ,           
		         ,        ,       
		    UI ,        

	GCD   :
		      
		             ,    
		GCD     @autoreleasepool

		       ,    dispatch_sync    
		dispatch_async           
		           UI ,        
	  :
		                

		    :
		1,          ,      
		2,  allocWithZone  
			allocWithZone            ,        ,
			     ,            
		3,  sharedXXX   ,       
 */
- (void)viewDidLoad
{
    [super viewDidLoad];
	//      ,  UI  
    [self setupUI];
    //        ,NSOperationQueue
    self.operationQueue = [[NSOperationQueue alloc]init];
}
//      ,  UI  
- (void)setupUI
{
    //          
    NSMutableSet *imageSet = [NSMutableSet setWithCapacity:28];
    //     17   ,      4 ,    7 (    )
	//        80,  50
    NSInteger w = 80;
    NSInteger h = 50;
	//   7  X 4   
    for (NSInteger row = 0; row < 7; row++) {
        for (NSInteger col = 0; col < 4; col++) {
            //        
			//               x  
			//               y  
            NSInteger x = col * w;
            NSInteger y = row * h;
            UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(x, y, w, h)];
            /*          ,    
            NSInteger index = (row * 4 + col) % 17 + 1;
            NSString *imageName = [NSString stringWithFormat:@"NatGeo%02d.png", index];
            UIImage *image = [UIImage imageNamed:imageName];
            [imageView setImage:image];
			*/
			//             ,      imageView,      
            [self.view addSubview:imageView];
            [imageSet addObject:imageView];
        }
    }
	//      NSSet,     imageSet,              
    self.imageViewSet = imageSet;
    //     
    UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [btn setFrame:CGRectMake(110, 385, 100, 40)];
    [btn setTitle:@"    " forState:UIControlStateNormal];
    [btn addTarget:self action:@selector(click) 
							forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:btn];
}
#pragma mark        ,    
- (void)click
{
	//   GCD     
    [self gcdLoad];
}
//     NSThread,   detach  ,  alloc    ,   start  
- (void)threadLoad
{
	//       NSSet     imageView    
    for (UIImageView *imageView in self.imageViewSet) {        
        //   1,   ,detach  ,  28   ,     threadLoadImage  
        [NSThread detachNewThreadSelector:@selector(threadLoadImage:)
									toTarget:self withObject:imageView];
        //   2,alloc    ,         ,    threadLoadImage  
        NSThread *thread = [[NSThread alloc]initWithTarget:self
					selector:@selector(threadLoadImage:) object:imageView];
		// alloc     ,    start   			
        [thread start];
    }
}
// NSThread     :      
- (void)threadLoadImage:(UIImageView *)imageView
{
	//   imageView   
    //         autoreleasepool
    @autoreleasepool {
        // 28   ,       1  
        [NSThread sleepForTimeInterval:1.0f];        
        NSInteger index = arc4random_uniform(17) + 1;
        NSString *imageName = [NSString stringWithFormat:@"NatGeo%02d.png",
															index];
        UIImage *image = [UIImage imageNamed:imageName];
        // imageView         setImage  ,  UI,    image
        [imageView performSelectorOnMainThread:@selector(setImage:)
										withObject:image waitUntilDone:YES];
    }
}
#pragma mark NSOperation  
//     2,NSXxxOperation      
- (void)operationDemo
{
    NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"   %@", [NSThread currentThread]);
    }];
    NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"   %@", [NSThread currentThread]);
    }];
    NSBlockOperation *op3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"   %@", [NSThread currentThread]);
    }];
    // Dependency  ,1  ,   2,    3
    //   :          
    //   :        ,    
    [op2 addDependency:op1];
    [op3 addDependency:op2];
	//  NSOperation       NSOperationQueue,      
    [self.operationQueue addOperation:op3];
    [self.operationQueue addOperation:op1];
    [self.operationQueue addOperation:op2];
}
//     2,NSBlockOperation
- (void)operationBlockLoad
{
	//       NSSet,    imageView    
    for (UIImageView *imageView in self.imageViewSet) {
		//        NSOperation
        NSBlockOperation *op = [NSBlockOperation blockOperationWithBlock:^{
			//                ,,operationLoadImage
            [self operationLoadImage:imageView];
        }];
        //               ,   , :     ~
        [self.operationQueue addOperation:op];
    }
}
//     2,NSInvocationOperation
-(void)operationLoad
{
    // NSOperationQueue  :                
	//     20   ,            4   
    [self.operationQueue setMaxConcurrentOperationCount:4];
	//       NSSet,    imageView    
    for (UIImageView *imageView in self.imageViewSet) {
		//        NSOperation
        NSInvocationOperation *op = [[NSInvocationOperation alloc]
				initWithTarget:self selector:@selector(operationLoadImage:) 
				object:imageView];
        //       operation start  ,           ,        
        [op start];
        //      Operation       ,            , :    
        [self.operationQueue addOperation:op];
    }
}
//     2,NSXxxOperation       ,      
- (void)operationLoadImage:(UIImageView *)imageView
{
    //         autoreleasepool
    @autoreleasepool {
        //   imageView   
		//       
        [NSThread sleepForTimeInterval:1.0f];
        NSInteger index = arc4random_uniform(17) + 1;
        NSString *imageName = [NSString stringWithFormat:@"NatGeo%02d.png",
															index];
        UIImage *image = [UIImage imageNamed:imageName];
        //            UI,    NSOperationQueue mainQueue
        [[NSOperationQueue mainQueue]addOperationWithBlock:^{
            [imageView setImage:image];
        }];
    }
}
//     3,GCD,      ,               
- (void)gcdDemo
{
    /*
     1.   global  
       :dispatch_get_global_queue(      )
        :DISPATCH_QUEUE_PRIORITY_DEFAULT
            (  )   ,   N   
     
     2.     
       :dispatch_queue_create(      ,         )
       :        ,      @
	      ,        
     
     3.    
          
       :dispatch_get_main_queue(     )
     
      gcd ,                  ,        
		           ,       
		         ,    ,   ,         
	 
	   dispatch_
       async   ,    
        priority,         
     1.             
     1)     ,             ,               
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
         ,    ,   get
     DISPATCH_QUEUE_SERIAL    
     
    dispatch_queue_t queue = dispatch_queue_create("myQueue",
									  DISPATCH_QUEUE_SERIAL);
	GCD   C     
	    :
	            ,         ,                  
	                 block
	          ,                
	GCD  FIFO    dispatch queue,               
	dispatch_notify               ,       
	GCD  :
	    :                    
	    :                    
	   :                      
*/
    //    ,        
    dispatch_queue_t queue = dispatch_get_main_queue();
    // 2)             ,             
    dispatch_async(queue, ^{
        NSLog(@"  1 %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"  2 %@", [NSThread currentThread]);
    });
    dispatch_async(queue, ^{
        NSLog(@"  3 %@", [NSThread currentThread]);
    });
}
//     3, GCD    ,       , NSSet   imageView    
- (void)gcdLoad
{
    // 1)       ,      
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
	//       NSSet,    imageView    
    for (UIImageView *imageView in self.imageViewSet) {
        // 2)             ,  N   ,       
        dispatch_async(queue, ^{
            NSLog(@"GCD- %@", [NSThread currentThread]);
            NSInteger index = arc4random_uniform(17) + 1;
            NSString *imageName = [NSString stringWithFormat:@"NatGeo%02d.png",
																index];
            //             image     
            UIImage *image = [UIImage imageNamed:imageName];
            // 3)                ,  
            dispatch_async(dispatch_get_main_queue(), ^{
                NSLog(@"    - %@", [NSThread currentThread]);
                [imageView setImage:image];
            });
        });
    }
}
@end

H:/1007/03_다중 스레드매표MainViewController.m
//  MainViewController.m
//     -03.  
//  Created by apple on 13-10-7.
/*
    
	  30      (        ,    )
	             
	        ,      
	           ,          
	               (     UI)
      
	   :    UI
	  1:   1    
	  2:   2    
	            
*/
#import "MainViewController.h"
#import "Ticket.h"
@interface MainViewController ()
@property (weak, nonatomic) UITextView *textView;
@property (strong, nonatomic) NSOperationQueue *operationQueue;
@end
@implementation MainViewController
- (void)viewDidLoad
{
    [super viewDidLoad];
    //        
    UITextView *textView = [[UITextView alloc]initWithFrame:self.view.bounds];
    //     
    [textView setEditable:NO];
    [self.view addSubview:textView];
    self.textView = textView;
    //      30  
    [Ticket sharedTicket].tickets = 30;
    //        ,NSOperationQueue
    self.operationQueue = [[NSOperationQueue alloc]init];
    //        ,    
    [self operationSales];
}
//        :NSOperation
- (void)operationSales
{
    //   ,operation             
    //       ,         :      
    [self.operationQueue setMaxConcurrentOperationCount:2];
    [self.operationQueue addOperationWithBlock:^{
        [self operationSaleTicketWithName:@"op-1"];
    }];
    [self.operationQueue addOperationWithBlock:^{
        [self operationSaleTicketWithName:@"op-2"];
    }];
    [self.operationQueue addOperationWithBlock:^{
        [self operationSaleTicketWithName:@"op-3"];
    }];
}
//        :NSOperation       
- (void)operationSaleTicketWithName:(NSString *)name
{
    while (YES) {
        //    synchronized     ,        /       
        @synchronized(self) {
            //        
            if ([Ticket sharedTicket].tickets > 0) {
                [Ticket sharedTicket].tickets--;
                //   ,                  ,          
                NSString *str = [NSString stringWithFormat:
									@"     %d      %@", 
									[Ticket sharedTicket].tickets, name];
                
                //  mainQueue      UI
                [[NSOperationQueue mainQueue]addOperationWithBlock:^{
					//        ,        ,        
                    [self appendContent:str];
                }];
            } else {
                NSLog(@"     %@ %@", name, [NSThread currentThread]);
                break;
            }
        }
        //       ,     ,      
        if ([name isEqualToString:@"op-1"]) {
            [NSThread sleepForTimeInterval:0.6f];
        } else {
            [NSThread sleepForTimeInterval:0.4f];
        }
    }
}
#pragma mark   UI,       ,      
- (void)appendContent:(NSString *)text
{
    // 1.               
    NSMutableString *str = [NSMutableString 
							stringWithString:self.textView.text];
    // 2.  text   textView     
    [str appendFormat:@"%@
", text]; // 3. , textView [self.textView setText:str]; // 4. textView , // 1 index, 2 NSRange range = NSMakeRange(str.length - 1, 1); // 5. [self.textView scrollRangeToVisible:range]; } // :NSThread - (void)threadSales { // , [NSThread detachNewThreadSelector:@selector(threadSaleTicketWithName:) toTarget:self withObject:@"thread-1"]; // , [NSThread detachNewThreadSelector:@selector(threadSaleTicketWithName:) toTarget:self withObject:@"thread-2"]; } // :NSThread - (void)threadSaleTicketWithName:(NSString *)name { // NSThread , @autoreleasepool @autoreleasepool { while (YES) { // synchronized , / @synchronized(self) { if ([Ticket sharedTicket].tickets > 0) { [Ticket sharedTicket].tickets--; NSString *str = [NSString stringWithFormat: @" %d %@", [Ticket sharedTicket].tickets, name]; // MainThread UI // , , [self performSelectorOnMainThread: @selector(appendContent:) withObject:str waitUntilDone:YES]; } else { break; } } // , , if ([name isEqualToString:@"thread-1"]) { [NSThread sleepForTimeInterval:1.0f]; } else { [NSThread sleepForTimeInterval:0.1f]; } } } } // :GCD, - (void)gcdSales_without_group { // 1) dispatch_queue_t queue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 2) dispatch_async(queue, ^{ [self gcdSaleTicketWithName:@"gcd-1"]; }); dispatch_async(queue, ^{ [self gcdSaleTicketWithName:@"gcd-2"]; }); dispatch_async(queue, ^{ [self gcdSaleTicketWithName:@"gcd-3"]; }); } // :GCD, , - (void)gcdSales_with_group { // 1) dispatch_queue_t queue = dispatch_get_global_queue( DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); // 2. GCD , // , , // 3. dispatch_group_t group = dispatch_group_create(); // 4. dispatch_group_async(group, queue, ^{ [self gcdSaleTicketWithName:@"gcd-1"]; }); dispatch_group_async(group, queue, ^{ [self gcdSaleTicketWithName:@"gcd-2"]; }); // 3) , , ~ dispatch_group_notify(group, queue, ^{ NSLog(@" "); }); } // :GCD - (void)gcdSaleTicketWithName:(NSString *)name { while (YES) { // synchronized , / @synchronized(self) { if ([Ticket sharedTicket].tickets > 0) { [Ticket sharedTicket].tickets--; // NSString *str = [NSString stringWithFormat:@" %d, %@", [Ticket sharedTicket].tickets, name]; // dispatch_get_main_queue UI dispatch_sync(dispatch_get_main_queue(), ^{ // , , [self appendContent:str]; }); } else { break; } } // , , if ([name isEqualToString:@"gcd-1"]) { [NSThread sleepForTimeInterval:1.0f]; } else { [NSThread sleepForTimeInterval:0.2f]; } } } @end

H:/1007/03_다중 스레드매표단일 예Ticket.h
//  Ticket.h
//     -03.  
//  Created by apple on 13-10-7.
//  Copyright (c) 2013  itcast. All rights reserved.

#import <Foundation/Foundation.h>

@interface Ticket : NSObject

//         
+ (Ticket *)sharedTicket;

//        ,                   
//           ,                 
//   :  atomic  ,       ,         ,      
//   ,atomic  ,   @synchronized(   )    

//    atomic
@property (assign, atomic) NSInteger tickets;

@end

H:/1007/03_다중 스레드매표단일 예Ticket.m
//  Ticket.m
//     -03.  
//  Created by apple on 13-10-7.
//  Copyright (c) 2013  itcast. All rights reserved.
#import "Ticket.h"
static Ticket *SharedInstance;
@implementation Ticket
/**
              
 1.                      
    static Ticket *SharedInstance
 2.   allocWithZone  ,   dispatch_once_t,           ,
                 
 3.      shared             ,       ,         
       dispatch_once_t           
	
               
 
        ,                   
           ,                 
 
   :  atomic  ,       ,         ,       
   ,atomic  ,   @synchronized(   )    
 */
//            ,       ,         
//            ,                    
+ (id)allocWithZone:(NSZone *)zone
{
    //       ,              
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        SharedInstance = [super allocWithZone:zone];
    });
    return SharedInstance;
}
//         ,       
+ (Ticket *)sharedTicket
{
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        SharedInstance = [[Ticket alloc]init];
    });
    return SharedInstance;
}
@end

좋은 웹페이지 즐겨찾기