Skip to content

Commit 11aeb3d

Browse files
committed
Added reference graph diagram to Hook
1 parent 94dd469 commit 11aeb3d

1 file changed

Lines changed: 32 additions & 4 deletions

File tree

Sources/InterposeKit/Hooks/Hook.swift

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,39 @@ public final class Hook {
1313
build: @escaping HookBuilder<MethodSignature, HookSignature>
1414
) throws {
1515
self.makeStrategy = { hook in
16+
// Hook should never be deallocated when invoking `makeHookIMP()`, as this only
17+
// occurs during strategy installation, which is triggered from a live hook instance.
18+
//
19+
// To ensure this, a strong reference cycle is intentionally created when the hook
20+
// is applied: the strategy installs a block-based IMP (stored in `appliedHookIMP`)
21+
// that retains a hook proxy, which in turn holds a strong reference to the hook.
22+
// This keeps the hook alive while it is applied, allowing access to its original
23+
// implementation.
24+
//
25+
// When not applied (i.e. prepared or reverted), `makeHookIMP` captures the hook
26+
// weakly to avoid premature retention, causing the hook to be deallocated when
27+
// the client releases it.
28+
//
29+
// Reference graph:
30+
// +------------------+
31+
// | Client |
32+
// +------------------+
33+
// |
34+
// v
35+
// +------------------+ +------------------+ weak
36+
// | HookProxy |---->| Hook |< - - - - - - -+
37+
// +------------------+ +------------------+ |
38+
// ^ | |
39+
// | v |
40+
// | +------------------+ +------------------+
41+
// | | HookStrategy |---->| makeHookIMP |
42+
// | +------------------+ +------------------+
43+
// | |
44+
// | v
45+
// | +------------------+
46+
// +--------------| appliedHookIMP |
47+
// +------------------+
1648
let makeHookIMP: () -> IMP = { [weak hook] in
17-
18-
// Hook should never be deallocated when invoking `makeHookIMP()`, as this only
19-
// happens when installing implementation from within the strategy, which is
20-
// triggered from a live hook instance.
2149
guard let hook else {
2250
Interpose.fail(
2351
"""

0 commit comments

Comments
 (0)