本文共 14226 字,大约阅读时间需要 47 分钟。
深度围观block:第一集&第二集
本文由破船译自galloway!
深度围观block:第一集
void(^block)(void) = ^{ NSLog(@"I'm a block!"); };
void(^block)(int a) = ^{ NSLog(@"I'm a block! a = %i", a); };
int(^block)(void) = ^{ NSLog(@"I'm a block!"); return 1; };
int a = 1; void(^block)(void) = ^{ NSLog(@"I'm a block! a = %i", a); };
#importtypedef void(^BlockA)(void); __attribute__((noinline)) void runBlockA(BlockA block) { block(); } void doBlockA() { BlockA block = ^{ // Empty block }; runBlockA(block); }
.globl _runBlockA .align 2 .code 16 @ @runBlockA .thumb_func _runBlockA _runBlockA: @ BB#0: ldr r1, [r0, #12] bx r1
.globl _doBlockA .align 2 .code 16 @ @doBlockA .thumb_func _doBlockA _doBlockA: movw r0, :lower16:(___block_literal_global-(LPC1_0+4)) movt r0, :upper16:(___block_literal_global-(LPC1_0+4)) LPC1_0: add r0, pc b.w _runBlockA
.align 2 @ @__block_literal_global lock_literal_global: .long __NSConcreteGlobalBlock .long 1342177280 @ 0x50000000 .long 0 @ 0x0 .long ___doBlockA_block_invoke_0 .long ___block_descriptor_tmp
.align 2 .code 16 @ @__doBlockA_block_invoke_0 .thumb_func ___doBlockA_block_invoke_0 ___doBlockA_block_invoke_0: bx lr .section __DATA,__const .align 2 @ @__block_descriptor_tmp ___block_descriptor_tmp: .long 0 @ 0x0 .long 20 @ 0x14 .long L_.str .long L_OBJC_CLASS_NAME_ .section __TEXT,__cstring,cstring_literals L_.str: @ @.str .asciz "v4@?0" .section __TEXT,__objc_classname,cstring_literals L_OBJC_CLASS_NAME_: @ @"\01L_OBJC_CLASS_NAME_" .asciz "\001"
struct Block_descriptor { unsigned long int reserved; unsigned long int size; void (*copy)(void *dst, void *src); void (*dispose)(void *); }; struct Block_layout { void *isa; int flags; int reserved; void (*invoke)(void *, ...); struct Block_descriptor *descriptor; /* Imported variables. */ };
#import__attribute__((noinline)) void runBlockA(struct Block_layout *block) { block->invoke(); } void block_invoke(struct Block_layout *block) { // Empty block function } void doBlockA() { struct Block_descriptor descriptor; descriptor->reserved = 0; descriptor->size = 20; descriptor->copy = NULL; descriptor->dispose = NULL; struct Block_layout block; block->isa = _NSConcreteGlobalBlock; block->flags = 1342177280; block->reserved = 0; block->invoke = block_invoke; block->descriptor = descriptor; runBlockA(&block); }
#importtypedef void(^BlockA)(void); void foo(int); __attribute__((noinline)) void runBlockA(BlockA block) { block(); } void doBlockA() { int a = 128; BlockA block = ^{ foo(a); }; runBlockA(block); }
.globl _runBlockA .align 2 .code 16 @ @runBlockA .thumb_func _runBlockA _runBlockA: ldr r1, [r0, #12] bx r1
.globl _doBlockA .align 2 .code 16 @ @doBlockA .thumb_func _doBlockA _doBlockA: push {r7, lr} mov r7, sp sub sp, #24 movw r2, :lower16:(L__NSConcreteStackBlock$non_lazy_ptr-(LPC1_0+4)) movt r2, :upper16:(L__NSConcreteStackBlock$non_lazy_ptr-(LPC1_0+4)) movw r1, :lower16:(___doBlockA_block_invoke_0-(LPC1_1+4)) LPC1_0: add r2, pc movt r1, :upper16:(___doBlockA_block_invoke_0-(LPC1_1+4)) movw r0, :lower16:(___block_descriptor_tmp-(LPC1_2+4)) LPC1_1: add r1, pc ldr r2, [r2] movt r0, :upper16:(___block_descriptor_tmp-(LPC1_2+4)) str r2, [sp] mov.w r2, #1073741824 str r2, [sp, #4] movs r2, #0 LPC1_2: add r0, pc str r2, [sp, #8] str r1, [sp, #12] str r0, [sp, #16] movs r0, #128 str r0, [sp, #20] mov r0, sp bl _runBlockA add sp, #24 pop {r7, pc}
_doBlockA: // 1 push {r7, lr} mov r7, sp // 2 sub sp, #24 // 3 movw r2, :lower16:(L__NSConcreteStackBlock$non_lazy_ptr-(LPC1_0+4)) movt r2, :upper16:(L__NSConcreteStackBlock$non_lazy_ptr-(LPC1_0+4)) LPC1_0: add r2, pc ldr r2, [r2] str r2, [sp] // 4 mov.w r2, #1073741824 str r2, [sp, #4] // 5 movs r2, #0 str r2, [sp, #8] // 6 movw r1, :lower16:(___doBlockA_block_invoke_0-(LPC1_1+4)) movt r1, :upper16:(___doBlockA_block_invoke_0-(LPC1_1+4)) LPC1_1: add r1, pc str r1, [sp, #12] // 7 movw r0, :lower16:(___block_descriptor_tmp-(LPC1_2+4)) movt r0, :upper16:(___block_descriptor_tmp-(LPC1_2+4)) LPC1_2: add r0, pc str r0, [sp, #16] // 8 movs r0, #128 str r0, [sp, #20] // 9 mov r0, sp bl _runBlockA // 10 add sp, #24 pop {r7, pc}
.align 2 .code 16 @ @__doBlockA_block_invoke_0 .thumb_func ___doBlockA_block_invoke_0 ___doBlockA_block_invoke_0: ldr r0, [r0, #20] b.w _foo .section __TEXT,__cstring,cstring_literals L_.str: @ @.str .asciz "v4@?0" .section __TEXT,__objc_classname,cstring_literals L_OBJC_CLASS_NAME_: @ @"\01L_OBJC_CLASS_NAME_" .asciz "\001P" .section __DATA,__const .align 2 @ @__block_descriptor_tmp ___block_descriptor_tmp: .long 0 @ 0x0 .long 24 @ 0x18 .long L_.str .long L_OBJC_CLASS_NAME_
#importtypedef void(^BlockA)(void); void foo(NSString*); __attribute__((noinline)) void runBlockA(BlockA block) { block(); } void doBlockA() { NSString *a = @"A"; BlockA block = ^{ foo(a); }; runBlockA(block); }
.section __DATA,__const .align 4 @ @__block_descriptor_tmp ___block_descriptor_tmp: .long 0 @ 0x0 .long 24 @ 0x18 .long ___copy_helper_block_ .long ___destroy_helper_block_ .long L_.str1 .long L_OBJC_CLASS_NAME_
.align 2 .code 16 @ @__copy_helper_block_ .thumb_func ___copy_helper_block_ opy_helper_block_: ldr r1, [r1, #20] adds r0, #20 movs r2, #3 b.w __Block_object_assign .align 2 .code 16 @ @__destroy_helper_block_ .thumb_func ___destroy_helper_block_ estroy_helper_block_: ldr r0, [r0, #20] movs r1, #3 b.w __Block_object_dispose
转载地址:http://vyvsi.baihongyu.com/