Skip to content

Commit 0d9646d

Browse files
committed
Refactored ObjectHookStrategy._findParentHook(…)
1 parent 4c19c51 commit 0d9646d

File tree

1 file changed

+24
-23
lines changed

1 file changed

+24
-23
lines changed

Sources/InterposeKit/Hooks/HookStrategy/ObjectHookStrategy/ObjectHookStrategy.swift

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ final class ObjectHookStrategy: HookStrategy {
161161
}
162162
Interpose.log("Restored -[\(self.class).\(self.selector)] IMP: \(self.storedOriginalIMP!)")
163163
} else {
164-
let nextHook = self.findNextHook(selfHook: self.handle, topmostIMP: currentIMP)
164+
let nextHook = self._findParentHook(from: currentIMP)
165165
// Replace next's original IMP
166166
nextHook?.originalIMP = self.storedOriginalIMP
167167
}
@@ -174,31 +174,32 @@ final class ObjectHookStrategy: HookStrategy {
174174
// self.dynamicSubclass = nil
175175
}
176176

177-
// Find the hook above us (not necessarily topmost)
178-
private func findNextHook(selfHook: ObjectHookHandle, topmostIMP: IMP) -> ObjectHookHandle? {
179-
// We are not topmost hook, so find the hook above us!
180-
var impl: IMP? = topmostIMP
181-
var currentHook: ObjectHookHandle?
182-
repeat {
183-
// get topmost hook
184-
let hook: ObjectHookHandle? = ObjectHookRegistry.handle(for: impl!)
185-
if hook === selfHook {
186-
// return parent
187-
return currentHook
188-
}
189-
// crawl down the chain until we find ourselves
190-
currentHook = hook
191-
impl = hook?.originalIMP
192-
} while impl != nil
177+
/// Traverses the object hook chain to find the handle to the parent of this hook, starting
178+
/// from the topmost IMP for the hooked method.
179+
///
180+
/// This is used when removing an object hook to rewire the parent hook’s original IMP
181+
/// back to this hook’s original IMP, effectively unlinking it from the chain.
182+
///
183+
/// - Parameter topmostIMP: The IMP of the topmost installed hook.
184+
/// - Returns: The handle to the parent hook in the chain, or `nil` if topmost.
185+
private func _findParentHook(from topmostIMP: IMP) -> ObjectHookHandle? {
186+
var currentIMP: IMP? = topmostIMP
187+
var previousHandle: ObjectHookHandle?
188+
189+
while let imp = currentIMP {
190+
// Get the handle for the current IMP and stop if not found.
191+
guard let currentHandle = ObjectHookRegistry.handle(for: imp) else { break }
192+
193+
// If we’ve reached this hook, the previous one is its parent.
194+
if currentHandle === self.handle { return previousHandle }
195+
196+
previousHandle = currentHandle
197+
currentIMP = currentHandle.originalIMP
198+
}
199+
193200
return nil
194201
}
195202

196-
// /// Release the hook block if possible.
197-
// public override func cleanup() {
198-
// // remove subclass!
199-
// super.cleanup()
200-
// }
201-
202203
}
203204

204205
extension ObjectHookStrategy: CustomDebugStringConvertible {

0 commit comments

Comments
 (0)