File tree

1 file changed

+42
-21
lines changed

1 file changed

+42
-21
lines changed
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,12 @@
2525
#import <UIKit/UIKit.h>
2626
#import <objc/runtime.h>
2727

28+
#define MAX_PENDING_APP_DELEGATE_BLOCKS 8
29+
2830
static IMP g_original_setDelegate_imp = NULL;
2931
static Class g_app_delegate_class = nil;
30-
static void (^g_pending_app_delegate_block)(Class) = nil;
32+
static void (^g_pending_app_delegate_blocks[MAX_PENDING_APP_DELEGATE_BLOCKS])(Class) = {nil};
33+
static int g_pending_block_count = 0;
3134

3235
// Swizzled implementation of setDelegate:
3336
static void Firebase_setDelegate(id self, SEL _cmd, id<UIApplicationDelegate> delegate) {
@@ -40,17 +43,31 @@ static void Firebase_setDelegate(id self, SEL _cmd, id<UIApplicationDelegate> de
4043
NSLog(@"Firebase: UIApplication setDelegate: called with nil delegate (Swizzled)");
4144
}
4245

43-
if (g_pending_app_delegate_block && g_app_delegate_class) {
44-
NSLog(@"Firebase: Firebase_setDelegate executing pending block with delegate class: %s.",
45-
class_getName(g_app_delegate_class));
46-
g_pending_app_delegate_block(g_app_delegate_class);
47-
g_pending_app_delegate_block = nil; // Clear the block after execution (ARC handles release)
48-
} else if (g_pending_app_delegate_block && !g_app_delegate_class) {
49-
// This case: setDelegate was called with nil, but a block was pending.
50-
// The pending block expects a Class. We don't have one.
51-
// So, we should clear the pending block as it can no longer be satisfied.
52-
NSLog(@"Firebase: Firebase_setDelegate called with nil delegate, clearing pending block as it cannot be executed.");
53-
g_pending_app_delegate_block = nil;
46+
// Check and execute/clear g_pending_app_delegate_blocks
47+
if (g_app_delegate_class) { // Delegate is valid, execute pending blocks
48+
if (g_pending_block_count > 0) {
49+
NSLog(@"Firebase: Firebase_setDelegate executing %d pending block(s) with delegate class: %s.",
50+
g_pending_block_count, class_getName(g_app_delegate_class));
51+
for (int i = 0; i < g_pending_block_count; i++) {
52+
if (g_pending_app_delegate_blocks[i]) {
53+
g_pending_app_delegate_blocks[i](g_app_delegate_class);
54+
g_pending_app_delegate_blocks[i] = nil; // Release the block
55+
}
56+
}
57+
// All pending blocks processed, reset count.
58+
g_pending_block_count = 0;
59+
}
60+
} else { // Delegate is nil, clear any pending blocks
61+
if (g_pending_block_count > 0) {
62+
NSLog(@"Firebase: Firebase_setDelegate called with nil delegate, clearing %d pending block(s).", g_pending_block_count);
63+
for (int i = 0; i < g_pending_block_count; i++) {
64+
if (g_pending_app_delegate_blocks[i]) {
65+
g_pending_app_delegate_blocks[i] = nil; // Release the block
66+
}
67+
}
68+
// All pending blocks cleared, reset count.
69+
g_pending_block_count = 0;
70+
}
5471
}
5572

5673
if (g_original_setDelegate_imp) {
@@ -141,17 +158,21 @@ - (BOOL)application:(UIApplication *)application
141158
void ForEachAppDelegateClass(void (^block)(Class)) {
142159
if (g_app_delegate_class) {
143160
NSLog(@"Firebase: ForEachAppDelegateClass executing with stored delegate class: %s.",
144-
class_getName(g_app_delegate_class));
161+
class_getName(g_app_delegate_class));
145162
block(g_app_delegate_class);
146-
// Clear any pending block as we've now executed with a known delegate.
147-
if (g_pending_app_delegate_block) {
148-
g_pending_app_delegate_block = nil; // ARC handles release
149-
}
163+
// If the delegate is already known and we execute immediately,
164+
// any previously pending blocks should have been cleared by Firebase_setDelegate.
165+
// No need to touch g_pending_app_delegate_blocks here as they are for pre-setDelegate calls.
150166
} else {
151-
NSLog(@"Firebase: ForEachAppDelegateClass - delegate class not yet known. Saving block for later execution.");
152-
// If a block is already pending, the new one replaces it. ARC handles the old one.
153-
// Make sure to copy the block to move it to the heap.
154-
g_pending_app_delegate_block = [block copy];
167+
// Delegate class not yet known, try to queue the block.
168+
if (g_pending_block_count < MAX_PENDING_APP_DELEGATE_BLOCKS) {
169+
g_pending_app_delegate_blocks[g_pending_block_count] = [block copy];
170+
g_pending_block_count++;
171+
NSLog(@"Firebase: ForEachAppDelegateClass - delegate class not yet known. Saved block for later execution (pending count: %d).", g_pending_block_count);
172+
} else {
173+
NSLog(@"Firebase Error: ForEachAppDelegateClass - pending block queue is full (max %d). Discarding new block.", MAX_PENDING_APP_DELEGATE_BLOCKS);
174+
// Block is discarded.
175+
}
155176
}
156177
}
157178

0 commit comments

Comments
 (0)