@@ -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
204205extension ObjectHookStrategy : CustomDebugStringConvertible {
0 commit comments