Created
July 6, 2011 06:17
-
-
Save stuartcarnie/1066669 to your computer and use it in GitHub Desktop.
Nested blocks discussion
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
void RetrieveFriends(GameCenter& gameCenter, GKLocalPlayer* localPlayer) | |
{ | |
[localPlayer loadFriendsWithCompletionHandler:^(NSArray* friends, NSError* error) | |
{ | |
// 1. this block is copied and retained by loadFriendsWithCompletionHandler | |
// 2. When called, loadPlayersForIdentifiers:withCompletionHandler will copy and retain the block below, | |
// which doesn't exist until the outer block is called | |
[GKPlayer loadPlayersForIdentifiers:friends withCompletionHandler:^(NSArray* players, NSError* error2) | |
{ | |
// Finally, dispatch_async will copy and retain the block which is passed to it below | |
dispatch_async(dispatch_get_main_queue(), ^(void) | |
{ | |
TestLala(gameCenter); //, friends, players, error2); | |
}); | |
}]; | |
}]; | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
.globl _RetrieveFriends | |
.align 2 | |
.code 16 | |
.thumb_func _RetrieveFriends | |
_RetrieveFriends: | |
Leh_func_begin1: | |
push {r4, r5, r7, lr} | |
add r7, sp, #8 | |
sub sp, #56 | |
add r2, sp, #20 | |
movs r3, #0 | |
str r0, [r2, #32] | |
str r1, [r2, #28] | |
str r2, [sp, #16] | |
add r2, sp, #24 | |
ldr.n r4, LCPI1_0 | |
LPC1_0: | |
add r4, pc | |
ldr r4, [r4] | |
ldr r5, [sp, #16] | |
str r4, [r5, #4] | |
movs r4, #1 | |
lsls r4, r4, #30 | |
str r4, [r5, #8] | |
str r3, [r5, #12] | |
ldr.n r3, LCPI1_1 | |
LPC1_1: | |
add r3, pc | |
str r3, [r5, #16] | |
ldr.n r3, LCPI1_2 | |
LPC1_2: | |
add r3, pc | |
str r3, [r5, #20] | |
ldr r3, [r5, #32] | |
str r3, [r5, #24] | |
ldr r3, [r5, #28] | |
str r3, [r5] | |
ldr.n r4, LCPI1_3 | |
LPC1_3: | |
add r4, pc | |
str r1, [sp, #12] | |
ldr r1, [r4] | |
str r0, [sp, #8] | |
mov r0, r3 | |
blx _objc_msgSend | |
ldr r0, [sp, #12] | |
ldr r1, [sp, #8] | |
str r1, [sp, #4] | |
str r0, [sp] | |
subs r4, r7, #7 | |
subs r4, #1 | |
mov sp, r4 | |
pop {r4, r5, r7, pc} | |
.align 2 | |
LCPI1_0: | |
.long L__NSConcreteStackBlock$non_lazy_ptr-(LPC1_0+4) | |
.align 2 | |
LCPI1_1: | |
.long ___RetrieveFriends_block_invoke_1-(LPC1_1+4) | |
.align 2 | |
LCPI1_2: | |
.long ___block_descriptor_tmp_3.54-(LPC1_2+4) | |
.align 2 | |
LCPI1_3: | |
.long L_OBJC_SELECTOR_REFERENCES_1-(LPC1_3+4) | |
Leh_func_end1: | |
.align 2 | |
.code 16 | |
.thumb_func ___RetrieveFriends_block_invoke_1 | |
___RetrieveFriends_block_invoke_1: | |
Leh_func_begin2: | |
push {r4, r5, r6, r7, lr} | |
add r7, sp, #12 | |
sub sp, #72 | |
add r3, sp, #28 | |
movs r4, #0 | |
str r0, [r3, #40] | |
str r1, [r3, #36] | |
str r2, [r3, #32] | |
ldr r5, [r3, #40] | |
ldr r5, [r5, #20] | |
str r5, [r3] | |
str r3, [sp, #24] | |
add r3, sp, #36 | |
ldr.n r5, LCPI2_0 | |
LPC2_0: | |
add r5, pc | |
ldr r5, [r5] | |
ldr r6, [sp, #24] | |
str r5, [r6, #8] | |
movs r5, #1 | |
lsls r5, r5, #30 | |
str r5, [r6, #12] | |
str r4, [r6, #16] | |
ldr.n r4, LCPI2_1 | |
LPC2_1: | |
add r4, pc | |
str r4, [r6, #20] | |
ldr.n r4, LCPI2_2 | |
LPC2_2: | |
add r4, pc | |
str r4, [r6, #24] | |
ldr r4, [r6] | |
str r4, [r6, #28] | |
ldr.n r4, LCPI2_3 | |
LPC2_3: | |
add r4, pc | |
ldr r4, [r4] | |
str r4, [r6, #4] | |
ldr.n r5, LCPI2_4 | |
LPC2_4: | |
add r5, pc | |
str r1, [sp, #20] | |
ldr r1, [r5] | |
str r2, [sp, #16] | |
ldr r2, [r6, #36] | |
str r0, [sp, #12] | |
mov r0, r4 | |
blx _objc_msgSend | |
ldr r0, [sp, #16] | |
ldr r1, [sp, #20] | |
ldr r2, [sp, #12] | |
str r2, [sp, #8] | |
str r0, [sp, #4] | |
str r1, [sp] | |
subs r4, r7, #7 | |
subs r4, #5 | |
mov sp, r4 | |
pop {r4, r5, r6, r7, pc} | |
.align 2 | |
LCPI2_0: | |
.long L__NSConcreteStackBlock$non_lazy_ptr-(LPC2_0+4) | |
.align 2 | |
LCPI2_1: | |
.long ___RetrieveFriends_block_invoke_2-(LPC2_1+4) | |
.align 2 | |
LCPI2_2: | |
.long ___block_descriptor_tmp_2.52-(LPC2_2+4) | |
.align 2 | |
LCPI2_3: | |
.long L_OBJC_CLASSLIST_REFERENCES_$_0-(LPC2_3+4) | |
.align 2 | |
LCPI2_4: | |
.long L_OBJC_SELECTOR_REFERENCES_0-(LPC2_4+4) | |
Leh_func_end2: | |
.align 2 | |
.code 16 | |
.thumb_func ___RetrieveFriends_block_invoke_2 | |
___RetrieveFriends_block_invoke_2: | |
Leh_func_begin3: | |
push {r4, r5, r7, lr} | |
add r7, sp, #8 | |
sub sp, #64 | |
add r3, sp, #24 | |
movs r4, #0 | |
str r0, [r3, #36] | |
str r1, [r3, #32] | |
str r2, [r3, #28] | |
ldr r5, [r3, #36] | |
ldr r5, [r5, #20] | |
str r5, [r3] | |
str r1, [sp, #20] | |
add r1, sp, #28 | |
ldr.n r5, LCPI3_0 | |
LPC3_0: | |
add r5, pc | |
ldr r5, [r5] | |
str r5, [r3, #4] | |
movs r5, #1 | |
lsls r5, r5, #30 | |
str r5, [r3, #8] | |
str r4, [r3, #12] | |
ldr.n r4, LCPI3_1 | |
LPC3_1: | |
add r4, pc | |
str r4, [r3, #16] | |
ldr.n r4, LCPI3_2 | |
LPC3_2: | |
add r4, pc | |
str r4, [r3, #20] | |
ldr r4, [r3] | |
str r4, [r3, #24] | |
ldr.n r3, LCPI3_3 | |
LPC3_3: | |
add r3, pc | |
str r0, [sp, #16] | |
ldr r0, [r3] | |
str r2, [sp, #12] | |
blx _dispatch_async | |
ldr r0, [sp, #12] | |
ldr r1, [sp, #20] | |
ldr r2, [sp, #16] | |
str r2, [sp, #8] | |
str r0, [sp, #4] | |
str r1, [sp] | |
subs r4, r7, #7 | |
subs r4, #1 | |
mov sp, r4 | |
pop {r4, r5, r7, pc} | |
.align 2 | |
LCPI3_0: | |
.long L__NSConcreteStackBlock$non_lazy_ptr-(LPC3_0+4) | |
.align 2 | |
LCPI3_1: | |
.long ___RetrieveFriends_block_invoke_3-(LPC3_1+4) | |
.align 2 | |
LCPI3_2: | |
.long ___block_descriptor_tmp_1.50-(LPC3_2+4) | |
.align 2 | |
LCPI3_3: | |
.long L__dispatch_main_q$non_lazy_ptr-(LPC3_3+4) | |
Leh_func_end3: | |
.align 1 | |
.code 16 | |
.thumb_func ___RetrieveFriends_block_invoke_3 | |
___RetrieveFriends_block_invoke_3: | |
Leh_func_begin4: | |
push {r7, lr} | |
mov r7, sp | |
sub sp, #16 | |
add r1, sp, #8 | |
str r0, [r1, #4] | |
ldr r2, [r0, #20] | |
str r2, [r1] | |
str r0, [sp, #4] | |
mov r0, r2 | |
bl _TestLala | |
ldr r0, [sp, #4] | |
str r0, [sp] | |
mov sp, r7 | |
pop {r7, pc} | |
Leh_func_end4: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Looking at the assembly, you can see there are 3 separate symbols which represent each of the blocks (which are just functions),
___RetrieveFriends_block_invoke_1
,___RetrieveFriends_block_invoke_2
and___RetrieveFriends_block_invoke_3
.The only object that is would potentially need to be retained is the localPlayer parameter, however it is used immediately and no longer needed for any of the nested calls. We're also assuming that the gameCenter reference is likely a singleton or lives for a long time.