블럭 스택
함수 포인터와 비슷하지만, 힙 영역에 생성되는 코드 블럭. 저도 참 좋아하는데요. 블럭도 결국은 실행코드에 대한 포인터이므로 크기가 고정되어 있어서 배열로 만들거나 구조체에 넣을 수 있습니다. 제가 한 번 예제를 만들어보겠습니다.
#import <Foundation/Foundation.h> | |
typedef void(^block_t)(void); | |
typedef struct _stack { | |
unsigned int _size; | |
int _top; | |
block_t *blocks; | |
} blockStack_t; | |
typedef void* stackRef; | |
// method functions | |
// declaration | |
stackRef create_stack(unsigned int size); | |
void stack_push_block(stackRef stack, block_t block); | |
void stack_pop_block(stackRef stack); | |
void stack_flush_block(stackRef stack); | |
void release_stack(stackRef stack); | |
// method functions | |
// definitions | |
stackRef create_stack(unsigned int size) | |
{ | |
blockStack_t *stack = (blockStack_t *)malloc(sizeof(blockStack_t)); | |
stack->_size = size; | |
stack->_top = –1; | |
stack->blocks = (block_t *)malloc(sizeof(block_t) * size); | |
return (stackRef)stack; | |
} | |
void stack_push_block(stackRef stack, block_t block) | |
{ | |
blockStack_t *_stack = (blockStack_t *)stack; | |
if(_stack->_top == _stack->_size – 1) return; | |
_stack->_top += 1; | |
*(_stack->blocks + _stack->_top) = block; | |
} | |
void stack_pop_block(stackRef stack) | |
{ | |
blockStack_t *_stack = (blockStack_t *)stack; | |
if(_stack->_top > –1) { | |
(*(_stack->blocks + _stack->_top))(); | |
_stack->_top -= 1; | |
} | |
} | |
void stack_flush_block(stackRef stack) | |
{ | |
blockStack_t *_stack = (blockStack_t *)stack; | |
while(_stack->_top > –1) { | |
(*(_stack->blocks + _stack->_top))(); | |
_stack->_top -= 1; | |
} | |
} | |
void release_stack(stackRef stack) | |
{ | |
blockStack_t *_stack = (blockStack_t *)stack; | |
free(_stack->blocks); | |
free(_stack); | |
} | |
int main(int argc, char const *argv[]) | |
{ | |
@autoreleasepool{ | |
stackRef s = create_stack(10); | |
stack_push_block(s, ^(){NSLog(@"a");}); | |
stack_push_block(s, ^(){NSLog(@"b");}); | |
stack_push_block(s, ^(){NSLog(@"c");}); | |
stack_push_block(s, ^(){NSLog(@"d");}); | |
stack_pop_block(s); | |
stack_push_block(s, ^(){NSLog(@"e");}); | |
stack_push_block(s, ^(){NSLog(@"f");}); | |
stack_push_block(s, ^(){NSLog(@"g");}); | |
stack_flush_block(s); | |
release_stack(s); | |
} | |
return 0; | |
} | |
// 2013-06-05 00:03:41.374 blockStack[481:707] d | |
// 2013-06-05 00:03:41.376 blockStack[481:707] g | |
// 2013-06-05 00:03:41.376 blockStack[481:707] f | |
// 2013-06-05 00:03:41.376 blockStack[481:707] e | |
// 2013-06-05 00:03:41.377 blockStack[481:707] c | |
// 2013-06-05 00:03:41.377 blockStack[481:707] b | |
// 2013-06-05 00:03:41.377 blockStack[481:707] a | |
// [Finished in 0.0s] |