feat(performance): detect UIViewController lifecycle methods not calling super - #436
Merged
Merged
Conversation
…ing super (#376) Add SuperCallDetector — swizzles viewDidLoad, viewWillAppear, viewDidAppear, viewWillDisappear, and viewDidDisappear on UIViewController using IMP-replacement (method_setImplementation, not method_exchangeImplementations) to avoid NewRelic-style crashes. Per-instance lifecycle state is tracked via associated objects; when a later lifecycle method fires for a VC instance but an earlier one was never recorded, the earlier method is flagged as missing its super call. Public API: DebugSwift.Performance.SuperCallChecker with onDetect(_:), violations, ignoreClass(_:), setIgnoredClasses(_:), clearViolations(). UI: dedicated "Super Call Checker" section in Performance tab with a ResourcesGenericController listing violations. Tests: 18 tests covering violation recording, dedup, ignore list, callback dispatch, public API mirroring, and end-to-end detection with good/bad VCs. Co-authored-by: oh-my-pi <https://omp.sh>
…ation The new swizzle feature case was added to DebugSwiftSwizzleFeature but the test's expected array was not updated, causing testDebugSwiftSwizzleFeature_allCases to fail on CI. Co-authored-by: oh-my-pi <https://omp.sh>
DebugSwift: Coverage: 15.2
ExampleTests.xctest: Coverage: 97.04
Generated by 🚫 Danger Swift against b71a7ee |
Contributor
|
Did you cover |
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
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Implements #376 — detects UIViewController lifecycle methods that fail to call their
superimplementation.Approach
Swizzling: Uses IMP-replacement (
method_setImplementation) — notmethod_exchangeImplementations— to avoid the NewRelic crash pattern documented in #434. The 5 swizzled lifecycle methods:viewDidLoad,viewWillAppear,viewDidAppear,viewWillDisappear,viewDidDisappear.Detection logic: Per-instance lifecycle state is tracked via associated objects. When a later lifecycle method fires for a VC instance but an earlier one was never recorded (meaning its swizzled base IMP never ran), the earlier method is flagged as missing its
supercall.Public API
DebugSwift.Performance.SuperCallChecker:onDetect(_:)— register a callback for new violationsviolations— current list ofSuperCallViolationignoreClass(_:)/setIgnoredClasses(_:)— ignore specific classesclearViolations()— clear stored violationsUI
Dedicated "Super Call Checker" section in the Performance tab with a
ResourcesGenericControllerlisting violations. Guarded by.superCallDetectorinDebugSwiftSwizzleFeature— disabled by default, opt-in like the leak detector.Tests
18 tests in
ExampleTestscovering:SuperCallChecker↔SuperCallDetector)LifecycleEventordering and countAll tests pass:
Files Changed
Performance.SuperCallDetector.swift(new) — core detection logicSuperCallViolationsViewModel.swift(new) — violations list ViewModelSuperCallDetectorTests.swift(new) — 18 testsFeatureBase.swift—.superCallDetectorcaseFeatureHandling.swift—enableSuperCallDetector()wiringDebugSwift.Performance.swift—SuperCallCheckerpublic APIPerformance.Controller.swift— UI section, cell, navigationCloses #376