IOS_다중 스레드표를 팔다
// 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
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
Java 다중 스레드를 순차적으로 실행하는 몇 가지 방법 요약Java 다중 스레드를 순차적으로 실행하는 몇 가지 방법 요약 동료는 무심결에 이 문제를 제기하고 두 가지 방법을 직접 실천했다.물론 더 좋은 방법이 있을 거야. 방법 1 이런 방법은 비교적 흔히 볼 수 있는 해결 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.