Grand Central Dispatch(GCD)는 큐를 동기/비동기로 처리할수 있도록 도와주는 도구다. 쓰레드를 os 가 자동관리 및 분배해준다. 개발자는 큐에 태스크를 생성해서 넣어주면 OS가 자동으로 태스크들을 실행해주는 방식이다.
일단 자바의 쓰레드에 비해 사용하기 쉽다는 거다.
- Serial Queue : 순서대로 큐의 태스크를 실행한다. 한개가 끝나면 다음 태스크가 실행되는 방식이다. 단 큐는 여러개 만들수 있기 때문에 여러개의 큐에서 동시에 여러태스크를 동시에 (Concurrency)실행할수 있다.
- Concurrent Dispatch Queue: GDQ라고 불리며 , 여러태스트를 하나의 큐에서 동시에 진행한다. 동시라고 해서 일시에 시작하는건 아니고 큐에 푸시한 순서대로 동시에 실행되는 거다.
^{
NSLog(@"I am Block");
};;
void (^myBlock)(void) = ^{
NSLog(@"This is a Block");
};
// invoke
myBlock();
블럭 생성과 함수에서 람다(인터페이스? 입급함수?) 처럼 이용해보자.
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
UBPayInterface *interface = [UBPayInterface sharedInstance:FALSE];
BOOL isInitialized = [interface isInitalized1];
//---- 1.선언방식
^{
NSLog(@"I am Block");
};;
// 변수에 대입방법
void (^myBlock)(void) = ^{
NSLog(@"This is a Block");
};
// 사용
myBlock();
//---- 2.변수에 파라메터와 리턴값
// 리턴값 (^변수이름)(파라메터들) = ^(파라메터들) { 리턴값 } 형식이다.
NSString* (^getParameterAndReturnString)(NSString*, BOOL) = ^(NSString* name, BOOL isTrush){
NSString* helloYour = nil;
if (!isTrush) {
helloYour = [NSString stringWithFormat:@"%@, is a Liar", name];
}
return helloYour;
};
// 사용
NSLog(@"%@", getParameterAndReturnString(@"kim", FALSE));
//---- 3.블럭은 {} 스코프안에서 처리되기 때문에 외부의 변수를 기본적으로 읽을수 없다. 때문에 __block 키워드를 사용하여 블럭스코프외부의 변수에 제한적으로 접근할수 있다.
__block int outerVal = 100;
void (^canReadableOuterVal)(void) = ^(void){
outerVal = 50;
};
// 사용
canReadableOuterVal();
NSLog(@"%d", outerVal);
//---- 4.2 호출할때는 선언된 파라메터와 같은 형식으로 호출하면 된다.
//Java 인터페이스라면 useBlockParameterEx(new myInterface() { @Override sumSum(int num1, int num2) {NSLog(@"%d", num1 + num2);} })
[self useBlockParameterEx:^(int num1, int num2) {
NSLog(@"%d", num1 + num2);
}];
NSLog(@"%@", isInitialized ? @"초기화 성공" : @"초기화 실패" );
}
//---- 4.1 함수의 파라메터로 선언은 이렇게 한다.(람다처럼)
//Java 인터페이스라면 useBlockParameterEx(MyInterface argMyinterface) { argMyinterface.sumSum(10, 20); }
- (void) useBlockParameterEx: (void (^)(int, int)) sumSum {
sumSum(10, 20);
}
Dispatch Queues 디스패치큐 .
디스패치큐는 dispatch_get_main_queue(프로그램에서 사용하는 메인큐 싱글, 즉 시리얼 디스패치큐) 와 dispatch_get_global_queue(시스템에서 사용하는 동시성 큐, 콘커런트 큐) 와 프로그래머 직접 만드는 dispatch_queue_create(이 명령으로 쓰레드를 프로그래머만든다)이렇게 3종류가 있다.
- dispatch_get_global_queue (시스템에서관리)
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0) 형태로서 우선순위에 의해 High, Default, Low, Background 로 구분할수 있다. - dispatch_get_main_queue (우리 앱에 메인 쓰레드)
- dispatch_queue_create (사용자가 생성한 쓰레드)
dispatch_queue_create("this area is for a log", DISPATCH_QUEUE_SERIAL) 형태이며DISPATCH_QUEUE_SERIAL, DISPATCH_QUEUE_CONCURRENT 두가지 생성옵션과 sync, Async 실행방식으로 구분된다.
sync - 릴레이 처럼 출발한 순서대로
//---- 5. Serial 큐.
dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
dispatch_sync(queue, ^{ NSLog(@"-> 1"); });
dispatch_sync(queue, ^{ NSLog(@"-> 2"); });
dispatch_sync(queue, ^{ NSLog(@"-> 3"); });
//---- 5-1. Serial 큐 지연시키기.
dispatch_time_t pushTime3s = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC));
dispatch_sync(queue, ^{ NSLog(@"-> 5"); });
dispatch_after(pushTime3s,queue, ^{ NSLog(@"-> 6"); });
//---- 5-2. Serial 큐 지연시키기.
// 일단 블럭시키고 시간이 걸리는 작업을 하자 8->6 이 예상되지만, 블럭킹처리시간으로 인해 큐에 추가되는 순서는 6->8
// 시간지연을 주더라도 해당시간에 실행되는것이아니라 해당시간에 큐에 추가하려고 하는거다.
// 따라서 긴시간 작업하던 7의 중간에 6이 끼어들어추가하려해서 추가됬고, 8이 그다음에 추가된거다.주의해야한다.
typedef void (^iambloking)(void);
iambloking blokinghehe = ^{
NSMutableArray *array = [[NSMutableArray alloc] init];
for ( long i = 0; i < 100000000; i++ ) {
[array addObject:[NSNumber numberWithLong:i]];
}};
dispatch_sync(queue, ^{ NSLog(@"-> 7");blokinghehe(); }); // 오래걸리는 블럭킹을 부르자
dispatch_sync(queue, ^{ NSLog(@"-> 8"); });
//1,2,3,4,5,7(wait),6,8
Async - 마라톤처럼 도착한 순서대로
//---- 5. Serial 큐.
dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_SERIAL);
dispatch_async(queue, ^{ NSLog(@"-> 1"); });
dispatch_async(queue, ^{ NSLog(@"-> 2"); });
dispatch_async(queue, ^{ NSLog(@"-> 3"); });
//---- 5-1. Serial 큐 지연시키기.
dispatch_time_t pushTime3s = dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC));
dispatch_async(queue, ^{ NSLog(@"-> 5"); });
dispatch_after(pushTime3s,queue, ^{ NSLog(@"-> 6"); });
//---- 5-2. Serial 큐 지연시키기.
// 일단 블럭시키고 시간이 걸리는 작업을 하자 8->6 이 예상되지만, 블럭킹처리시간으로 인해 큐에 추가되는 순서는 6->8
// 시간지연을 주더라도 해당시간에 실행되는것이아니라 해당시간에 큐에 추가하려고 하는거다.
// 따라서 긴시간 작업하던 7의 중간에 6이 끼어들어추가하려해서 추가됬고, 8이 그다음에 추가된거다.주의해야한다.
typedef void (^iambloking)(void);
iambloking blokinghehe = ^{
NSMutableArray *array = [[NSMutableArray alloc] init];
for ( long i = 0; i < 100000000; i++ ) {
[array addObject:[NSNumber numberWithLong:i]];
}};
dispatch_async(queue, ^{
NSLog(@"-> 7");
dispatch_async(dispatch_queue_create("innerQ", DISPATCH_QUEUE_SERIAL), ^{ NSLog(@"-> innerQ"); blokinghehe(); });
}); // 오래걸리는 블럭킹을 부르자
dispatch_async(queue, ^{ NSLog(@"-> 8"); });
//1,2,3,4,5,7(wait),8,6
dispatch_queue_t queue = dispatch_queue_create("test", DISPATCH_QUEUE_CONCURRENT);
사용법은 SERIAL과 같다.
C. Group 생성 - 모든 태스크가 끝난는지 판단
//---- 6. Dispatch Group
dispatch_queue_t queueG = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queueC, ^{
[NSThread sleepForTimeInterval:1];
NSLog(@"Done: %d", 1);
});
// 그룹에 추가
dispatch_group_enter(group);
//콜백 정의
typedef void (^blk_t)(void (^callback)(void));
blk_t callback = ^(void (^callback)(void)){
NSMutableArray *array = [[NSMutableArray alloc] init];
for ( long i = 0; i < 35000000; i++ ) {
[array addObject:[NSNumber numberWithLong:i]];
}
callback();
};
//콜백호출
callback(^{
//콜백 함수로 그룹에 추가한게 끝이라고 하게함
dispatch_group_leave(group);
});
//enter->leave가 끝나야 다음 태스크 실행
dispatch_group_async(group, queueG, ^{ NSLog(@"Done' %f", 1.5); });
dispatch_group_notify(group, queueG, ^{
NSLog(@"All tasks are done!");
});
dispatch_group_async(group, queueG, ^{
//[NSThread sleepForTimeInterval:2];
NSLog(@"Done: %d", 2);
});
dispatch_group_async(group, queueG, ^{
// [NSThread sleepForTimeInterval:1];
NSLog(@"Done: %d", 3);
});
//https://padgom.tistory.com/entry/iOS-%EA%B8%B0%EB%B3%B8-GCDGrand-Central-Dispatch-%EC%82%AC%EC%9A%A9%ED%95%98%EA%B8%B0
D. Barrier 특정 지점에서 장벽? 을 쳐서 그부분까지 실행하도록 하고, 다음 태스크들을 기다리게하는거
0 comments:
댓글 쓰기